使用纯Java配置时,我花了很多时间来围绕spring-security进行研究。要使其正常工作,涉及几个步骤。应该遵循这些原则。基本过程如下:
创建自定义过滤器以检查请求以获取特定的授权信息
每个过滤器返回null(如果未找到该类型的授权),或者返回自定义AbstractAuthenticationToken
如果过滤器返回令牌,则每个AuthenticationProvider的support(class)方法将被调用,并且该令牌如果应尝试进行身份验证,则返回true | false
然后将在支持令牌的AuthenticationProvider上调用tryAuthentication。在这里,您可以进行任何服务调用以验证用户身份。然后,您可以抛出LoginException或调用authentication.setAuthenticated(true)并返回用于成功认证的令牌。
我一直在使用此设置一段时间,以支持各种身份验证方法(签名请求,用户名/密码,oauth等),并且效果很好。
您还可以将AuthenticationSuccessHandler和AuthenticationFailuersHandler传递到自定义安全过滤器,以提供自定义重定向策略和故障处理。
另外,请务必在过滤器的构造函数中设置ant匹配器,以控制过滤器也应用哪种url模式。例如,ldap请求过滤器可能需要与任何请求“ /
*”一起检查,而用户名/密码过滤器仅可以在POST到/ login或类似的地方进行检查。
示例代码:
1)为您要支持的每种身份验证类型创建自定义AuthenticationToken
public class LDAPAuthorizationToken extends AbstractAuthenticationToken { private String token; public LDAPAuthorizationToken( String token ) { super( null ); this.token = token; } public Object getCredentials() { return token; } public Object getPrincipal() { return null; }}public class OTPAuthorizationToken extends UsernamePasswordAuthenticationToken { private String otp; public OTPAuthorizationToken( String username, String password, String otp ) { super( username, password ); this.otp = otp; } public String getOTP() { return otp; }}2)为每种类型创建自定义安全过滤器
public class LDAPAuthorizationFilter extends AbstractAuthenticationProcessingFilter { @Autowired private UserDetailsService userDetailsService; public LDAPAuthorizationFilter() { super( "/*" ); // allow any request to contain an authorization header } public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response ) throws AuthenticationException { if ( request.getHeader( "Authorization" ) == null ) { return null; // no header found, continue on to other security filters } // return a new authentication token to be processed by the authentication provider return new LDAPAuthorizationToken( request.getHeader( "Authorization" ) ); }}public class OTPAuthorizationFilter extends AbstractAuthenticationProcessingFilter { @Autowired private UserDetailsService userDetailsService; public OTPAuthorizationFilter() { super( "/otp_login" ); } public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response ) throws AuthenticationException { if ( request.getParameter( "username" ) == null || request.getParameter( "password" ) == null || request.getParameter( "otp" ) == null ) { return null; } // return a new authentication token to be processed by the authentication provider return new OTPAuthorizationToken( request.getParameter( "username" ), request.getParameter( "password" ), request.getParameter( "otp" ) ); }}3)创建自定义AuthenticationProviders
public class LDAPAuthenticationProvider implements AuthenticationProvider { @Autowired private MyAuthenticationService sampleService; @Override public Authentication authenticate( Authentication authentication ) throws AuthenticationException { LDAPAuthorizationToken auth = (LDAPAuthorizationToken)authentication; String username = sampleService.verifyToken( auth.getCredentials() ); if ( username == null ) { throw new LoginException( "Invalid Token" ); } auth.setAuthenticated( true ); return auth; } @Override public boolean supports( Class<?> authentication ) { if ( authentication.isAssignableFrom( LDAPAuthorizationToken.class ) ) { return true; } return false; }}public class OTPAuthenticationProvider implements AuthenticationProvider { @Autowired private MyAuthenticationService sampleService; @Override public Authentication authenticate( Authentication authentication ) throws AuthenticationException { OTPAuthorizationToken auth = (OTPAuthorizationToken)authentication; String error = sampleService.loginWithOTP( auth.getPrincipal(), auth.getCredentials(), auth.getOTP() ); if ( error != null ) { throw new LoginException( error ); } auth.setAuthenticated( true ); return auth; } @Override public boolean supports( Class<?> authentication ) { if ( authentication.isAssignableFrom( OTPAuthorizationToken.class ) ) { return true; } return false; }}4)配置弹簧安全性
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure( HttpSecurity http ) throws Exception { // configure filters http.addFilterBefore( new LDAPAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class ); http.addFilterBefore( new OTPAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class ); // configure authentication providers http.authenticationProvider( new LDAPAuthenticationProvider() ); http.authenticationProvider( new OTPAuthenticationProvider() ); // disable csrf http.csrf().disable(); // setup security http.authorizeRequests() .anyRequest() .fullyAuthenticated() .and().httpBasic(); }}希望有帮助!



