1. 程式人生 > >自定義 Spring Security 4 的UserDetailsService和UserDetails

自定義 Spring Security 4 的UserDetailsService和UserDetails

首先在Spring的配置檔案中加入自定義UserDetailsService的配置,假如類的全名為com.cpwl.security.CpwlUserDetailsService並且加入了一個加密器:

<bean id="myUserDetailsService" class="com.cpwl.security.CpwlUserDetailsService"></bean>
<bean id="bcryptEncoder"
	class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
</bean>

<sec:authentication-manager>
	<sec:authentication-provider
		user-service-ref="myUserDetailsService">
		<sec:password-encoder ref="bcryptEncoder" />
	</sec:authentication-provider>
</sec:authentication-manager>

然後定義UserDetails的實現,這裡名叫User:
package com.cpwl.security;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class User implements UserDetails{
	private Long id;
	private String username;
	private String password;
	private boolean enabled;
	private Collection<? extends GrantedAuthority> authorities;
	
	public User(Long id, String username, String password, boolean enabled) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.enabled = enabled;
	}
	
	public User(Long id, String username, String password, boolean enabled,
			Collection<? extends GrantedAuthority> authorities) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.enabled = enabled;
		this.authorities = authorities;
	}
	public Long getId(){
		return this.id;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}
	@Override
	public String getPassword() {
		return password;
	}
	@Override
	public String getUsername() {
		return username;
	}
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}
	@Override
	public boolean isEnabled() {
		return enabled;
	}

	@Override
	public String toString() {
		return "MyUserDetails [id=" + id + ", username=" + username
				+ ", password=" + password + ", enabled=" + enabled
				+ ", authorities=" + authorities + "]";
	}


}

最後定義我們的UserDetailsService:
package com.cpwl.security;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class CpwlUserDetailsService implements UserDetailsService {

	@Autowired
	JdbcTemplate jdbcTemplate;
	private final String sqlLoadUser;
	private final String sqlLoadAuthorities;
	private final RowMapper<User> myUserDetailsRowMapper;
	private final RowMapper<GrantedAuthority> authorityRowMapper;

	private static Logger logger = LoggerFactory
			.getLogger(CpwlUserDetailsService.class);

	public CpwlUserDetailsService() {
		super();
		sqlLoadUser = "SELECT id,username,password,enabled FROM user WHERE username=? OR phoneNumber=? OR email=?";
		sqlLoadAuthorities = "SELECT authority FROM view_role WHERE username=?";
		myUserDetailsRowMapper = new RowMapper<User>() {
			@Override
			public User mapRow(ResultSet rs, int rowNum) throws SQLException {
				return new User(rs.getLong(1), rs.getString(2),
						rs.getString(3), rs.getBoolean(4));
			}
		};
		authorityRowMapper = new RowMapper<GrantedAuthority>() {
			@Override
			public GrantedAuthority mapRow(ResultSet rs, int rowNum)
					throws SQLException {
				return new SimpleGrantedAuthority(rs.getString(1));
			}
		};
	}

	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		try {
			User userFromQuery = jdbcTemplate.queryForObject(sqlLoadUser,
					myUserDetailsRowMapper, username, username, username);
			logger.debug("查詢得到使用者:{}", userFromQuery);
			List<GrantedAuthority> authorities = jdbcTemplate.query(
					sqlLoadAuthorities, authorityRowMapper, username);
			logger.debug("得到其許可權:{}", authorities);
			return new User(userFromQuery.getId(), userFromQuery.getUsername(),
					userFromQuery.getPassword(), userFromQuery.isEnabled(),
					authorities);
		} catch (EmptyResultDataAccessException e) {
			logger.debug("查詢結果集為空:{}", username);
			throw new UsernameNotFoundException("使用者名稱或密碼不正確");
		}
	}

}