`

Spring Acegi框架鉴权的实现 (3)

阅读更多
代码
  1. public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {   
  2.     //~ Static fields/initializers =====================================================================================   
  3.     //这里是预定义好的对查询语句,对应于默认的数据库表结构,也可以自己定义查询语句对应特定的用户数据库验证表的设计   
  4.     public static final String DEF_USERS_BY_USERNAME_QUERY =   
  5.             "SELECT username,password,enabled FROM users WHERE username = ?";   
  6.     public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =   
  7.             "SELECT username,authority FROM authorities WHERE username = ?";   
  8.   
  9.     //~ Instance fields ================================================================================================   
  10.     //这里使用Spring JDBC来进行数据库操作   
  11.     protected MappingSqlQuery authoritiesByUsernameMapping;   
  12.     protected MappingSqlQuery usersByUsernameMapping;   
  13.     private String authoritiesByUsernameQuery;   
  14.     private String rolePrefix = "";   
  15.     private String usersByUsernameQuery;   
  16.     private boolean usernameBasedPrimaryKey = true;   
  17.   
  18.     //~ Constructors ===================================================================================================   
  19.     //在初始化函数中把查询语句设置为预定义的SQL语句   
  20.     public JdbcDaoImpl() {   
  21.          usersByUsernameQuery = DEF_USERS_BY_USERNAME_QUERY;   
  22.          authoritiesByUsernameQuery = DEF_AUTHORITIES_BY_USERNAME_QUERY;   
  23.      }   
  24.   
  25.     //~ Methods ========================================================================================================   
  26.   
  27.     protected void addCustomAuthorities(String username, List authorities) {}   
  28.   
  29.     public String getAuthoritiesByUsernameQuery() {   
  30.         return authoritiesByUsernameQuery;   
  31.      }   
  32.   
  33.     public String getRolePrefix() {   
  34.         return rolePrefix;   
  35.      }   
  36.   
  37.     public String getUsersByUsernameQuery() {   
  38.         return usersByUsernameQuery;   
  39.      }   
  40.   
  41.     protected void initDao() throws ApplicationContextException {   
  42.          initMappingSqlQueries();   
  43.      }   
  44.   
  45.     /**
  46.       * Extension point to allow other MappingSqlQuery objects to be substituted in a subclass
  47.       */  
  48.     protected void initMappingSqlQueries() {   
  49.         this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource());   
  50.         this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource());   
  51.      }   
  52.   
  53.     public boolean isUsernameBasedPrimaryKey() {   
  54.         return usernameBasedPrimaryKey;   
  55.      }   
  56.     //这里是取得数据库用户信息的具体过程   
  57.     public UserDetails loadUserByUsername(String username)   
  58.         throws UsernameNotFoundException, DataAccessException {   
  59.         //根据用户名在用户表中得到用户信息,包括用户名,密码和用户是否有效的信息   
  60.          List users = usersByUsernameMapping.execute(username);   
  61.   
  62.         if (users.size() == 0) {   
  63.             throw new UsernameNotFoundException("User not found");   
  64.          }   
  65.         //取集合中的第一个作为有效的用户对象   
  66.          UserDetails user = (UserDetails) users.get(0); // contains no GrantedAuthority[]   
  67.         //这里在权限表中去取得用户的权限信息,同样的返回一个权限集合对应于这个用户   
  68.          List dbAuths = authoritiesByUsernameMapping.execute(user.getUsername());   
  69.   
  70.          addCustomAuthorities(user.getUsername(), dbAuths);   
  71.   
  72.         if (dbAuths.size() == 0) {   
  73.             throw new UsernameNotFoundException("User has no GrantedAuthority");   
  74.          }   
  75.         //这里根据得到的权限集合来配置返回的User对象供以后使用   
  76.          GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]);   
  77.   
  78.          String returnUsername = user.getUsername();   
  79.   
  80.         if (!usernameBasedPrimaryKey) {   
  81.              returnUsername = username;   
  82.          }   
  83.   
  84.         return new User(returnUsername, user.getPassword(), user.isEnabled(), true, true, true, arrayAuths);   
  85.      }   
  86.   
  87.     public void setAuthoritiesByUsernameQuery(String queryString) {   
  88.          authoritiesByUsernameQuery = queryString;   
  89.      }   
  90.   
  91.     public void setRolePrefix(String rolePrefix) {   
  92.         this.rolePrefix = rolePrefix;   
  93.      }   
  94.   
  95.     public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) {   
  96.         this.usernameBasedPrimaryKey = usernameBasedPrimaryKey;   
  97.      }   
  98.   
  99.     public void setUsersByUsernameQuery(String usersByUsernameQueryString) {   
  100.         this.usersByUsernameQuery = usersByUsernameQueryString;   
  101.      }   
  102.   
  103.     //~ Inner Classes ==================================================================================================   
  104.   
  105.     /**
  106.       * 这里是调用Spring JDBC的数据库操作,具体可以参考对JDBC的分析,这个类的作用是把数据库查询得到的记录集合转换为对象集合 - 一个很简单的O/R实现
  107.       */  
  108.     protected class AuthoritiesByUsernameMapping extends MappingSqlQuery {   
  109.         protected AuthoritiesByUsernameMapping(DataSource ds) {   
  110.             super(ds, authoritiesByUsernameQuery);   
  111.              declareParameter(new SqlParameter(Types.VARCHAR));   
  112.              compile();   
  113.          }   
  114.   
  115.         protected Object mapRow(ResultSet rs, int rownum)   
  116.             throws SQLException {   
  117.              String roleName = rolePrefix + rs.getString(2);   
  118.              GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);   
  119.   
  120.             return authority;   
  121.          }   
  122.      }   
  123.   
  124.     /**
  125.       * Query object to look up a user.
  126.       */  
  127.     protected class UsersByUsernameMapping extends MappingSqlQuery {   
  128.         protected UsersByUsernameMapping(DataSource ds) {   
  129.             super(ds, usersByUsernameQuery);   
  130.              declareParameter(new SqlParameter(Types.VARCHAR));   
  131.              compile();   
  132.          }   
  133.   
  134.         protected Object mapRow(ResultSet rs, int rownum)   
  135.             throws SQLException {   
  136.              String username = rs.getString(1);   
  137.              String password = rs.getString(2);   
  138.             boolean enabled = rs.getBoolean(3);   
  139.              UserDetails user = new User(username, password, enabled, true, true, true,   
  140.                     new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});   
  141.   
  142.             return user;   
  143.          }   
  144.      }   
  145. }   
代码
  1. //这个UserDetail是从数据库中查询到的,这个authentication是从用户输入中得到的   
  2.     protected void additionalAuthenticationChecks(UserDetails userDetails,   
  3.          UsernamePasswordAuthenticationToken authentication)   
  4.         throws AuthenticationException {   
  5.          Object salt = null;   
  6.   
  7.         if (this.saltSource != null) {   
  8.              salt = this.saltSource.getSalt(userDetails);   
  9.          }   
  10.         //如果用户没有输入密码,直接抛出异常   
  11.         if (authentication.getCredentials() == null) {   
  12.             throw new BadCredentialsException(messages.getMessage(   
  13.                     "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),   
  14.                      includeDetailsObject ? userDetails : null);   
  15.          }   
  16.         //这里取得用户输入的密码   
  17.          String presentedPassword = authentication.getCredentials() == null ? "" : authentication.getCredentials().toString();   
  18.         //这里判断用户输入的密码是不是和数据库里的密码相同,这里可以使用passwordEncoder来对数据库里的密码加解密   
  19.         // 如果不相同,抛出异常,如果相同则鉴权成功   
  20.         if (!passwordEncoder.isPasswordValid(   
  21.                  userDetails.getPassword(), presentedPassword, salt)) {   
  22.             throw new BadCredentialsException(messages.getMessage(   
  23.                     "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),   
  24.                      includeDetailsObject ? userDetails : null);   
  25.          }   
  26.      } 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics