- GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]);
String returnUsername = user.getUsername();
if (!usernameBasedPrimaryKey) {
returnUsername = username;
}
return new User(returnUsername, user.getPassword(), user.isEnabled(), true, true, true, arrayAuths);
}
public void setAuthoritiesByUsernameQuery(String queryString) {
authoritiesByUsernameQuery = queryString;
}
public void setRolePrefix(String rolePrefix) {
this.rolePrefix = rolePrefix;
}
public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) {
this.usernameBasedPrimaryKey = usernameBasedPrimaryKey;
}
public void setUsersByUsernameQuery(String usersByUsernameQueryString) {
this.usersByUsernameQuery = usersByUsernameQueryString;
}
//~ Inner Classes ==================================================================================================
/**
* 这里是调用Spring JDBC的数据库操作,具体可以参考对JDBC的分析,这个类的作用是把数据库查询得到的记录集合转换为对象集合 - 一个很简单的O/R实现
*/
protected class AuthoritiesByUsernameMapping extends MappingSqlQuery {
protected AuthoritiesByUsernameMapping(DataSource ds) {
super(ds, authoritiesByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
String roleName = rolePrefix + rs.getString(2);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
return authority;
}
}
/**
* Query object to look up a user.
*/
protected class UsersByUsernameMapping extends MappingSqlQuery {
protected UsersByUsernameMapping(DataSource ds) {
super(ds, usersByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
String username = rs.getString(1);
String password = rs.getString(2);
boolean enabled = rs.getBoolean(3);
UserDetails user = new User(username, password, enabled, true, true, true,
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
return user;
}
}
}
从数据库中得到用户信息后,就是一个比对用户输入的信息和这个数据库用户信息的比对过程,这个比对过程在DaoAuthenticationProvider:- Java代码
- //这个UserDetail是从数据库中查询到的,这个authentication是从用户输入中得到的
- protected void additionalAuthenticationChecks(UserDetails userDetails,
- UsernamePasswordAuthenticationToken authentication)
- throws AuthenticationException {
- Object salt = null;
- if (this.saltSource != null) {
- salt = this.saltSource.getSalt(userDetails);
- }
- //如果用户没有输入密码,直接抛出异常
- if (authentication.getCredentials() == null) {
- throw new BadCredentialsException(messages.getMessage(
- "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
- includeDetailsObject ? userDetails : null);
- }
- //这里取得用户输入的密码
- String presentedPassword = authentication.getCredentials() == null ? "" : authentication.getCredentials().toString();
- //这里判断用户输入的密码是不是和数据库里的密码相同,这里可以使用passwordEncoder来对数据库里的密码加解密
- // 如果不相同,抛出异常,如果相同则鉴权成功
- if (!passwordEncoder.isPasswordValid(
- userDetails.getPassword(), presentedPassword, salt)) {
- throw new BadCredentialsException(messages.getMessage(
- "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
- includeDetailsObject ? userDetails : null);
- }
- }
- //这个UserDetail是从数据库中查询到的,这个authentication是从用户输入中得到的 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { Object salt = null; if (this.saltSource != null) { salt = this.saltSource.getSalt(userDetails); } //如果用户没有输入密码,直接抛出异常 if (authentication.getCredentials() == null) { throw new BadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), includeDetailsObject ? userDetails : null); } //这里取得用户输入的密码 String presentedPassword = authentication.getCredentials() == null ? "" : authentication.getCredentials().toString(); //这里判断用户输入的密码是不是和数据库里的密码相同,这里可以使用passwordEncoder来对数据库里的密码加解密 // 如果不相同,抛出异常,如果相同则鉴权成功 if (!passwordEncoder.isPasswordValid( userDetails.getPassword(), presentedPassword, salt)) { throw new BadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"), includeDetailsObject ? userDetails : null); } }
上面分析了整个Acegi进行验证的过程,从AuthenticationProcessingFilter中拦截Http请求得到用户输入的用户名和密码,这些用户输入的验证信息会被放到Authentication对象中持有并传递给AuthenticatioManager来对比在服务端的用户信息来完成整个鉴权。这个鉴权完成以后会把有效的用户信息放在一个Authentication中供以后的授权模块使用。在具体的鉴权过程中,使用了我们配置好的各种Provider以及对应的UserDetailService和Encoder类来完成相应的获取服务器端用户数据以及与用户输入的验证信息的
//这里根据得到的权限集合来配置返回的User对象供以后使用5
最新推荐文章于 2023-03-07 14:36:12 发布