16

我知道这已经被回答了很多次,但我很困惑。我的应用程序中已经有一个身份验证机制,我只想使用 Spring MVC 的授权部分。我正在使用 Spring MVC 3 和 Spring Security 3。

当我在互联网上搜索时,我发现了两个解决方案,第一个是只实现 AuthenticationProvider 接口。示例 1。第二个是实现UserDetails和UserDetailsS​​ervice,Example2所以我在这里迷路了。

- - 更新 - -

问题的第二部分在这里。以及解决方法。

4

1 回答 1

37

在大多数情况下,当仅使用用户名和密码进行身份验证和角色进行授权时,实现自己的 UserDetailsS​​ervice 就足够了。

那么用户名密码认证的流程一般如下:

  • 一个 spring 安全过滤器(基本身份验证/表单/..)获取用户名和密码,将其转换为 UsernamePasswordAuthentication 对象并将其传递给 AuthenticationManager
  • 身份验证管理器寻找可以处理 UsernamePasswordtokens 的候选提供者,在这种情况下是 DaoAuthenticationProvider 并传递令牌以进行身份​​验证
  • 身份验证提供程序调用方法 loadUserByUsername 接口并在用户不存在时抛出 UsernameNotFound 异常或返回包含用户名、密码和权限的 UserDetails 对象。
  • 然后,身份验证提供程序比较提供的 UsernamePasswordToken 和 UserDetails 对象的密码。(它还可以通过 PasswordEncoders 处理密码哈希)如果不匹配,则身份验证失败。如果匹配,则注册用户详细信息对象并将其传递给 AccessDecisionManager,后者执行授权部分。

因此,如果 DaoAuthenticationProvider 中的验证符合您的需求。然后你只需要实现你自己的 UserDetailsS​​ervice 并调整 DaoAuthenticationProvider 的验证。

使用 spring 3.1 的 UserDetailsS​​ervice 示例如下:

春天 XML:

<security:authentication-manager>
     <security:authentication-provider user-service-ref="myUserDetailsService" />
</security:authentication-manager>

<bean name="myUserDetailsService" class="x.y.MyUserDetailsService" />

UserDetailsS​​ervice 实现:

public MyUserDetailsService implements UserDetailsService {

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    //Retrieve the user from wherever you store it, e.g. a database 
    MyUserClass user = ...; 
    if (user == null) {
        throw new UsernameNotFoundException("Invalid username/password.");
    }
    Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("Role1","role2","role3");
    return new User(user.getUsername(), user.getPassword(), authorities);
}

}
于 2013-08-14T06:22:38.373 回答