@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().fullyAuthenticated()
.and()
.httpBasic();
}
@Configuration
protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
@Value("${ldap-${env}.manager.dn}")
private String managerDn;
@Value("${ldap-${env}.manager.pass}")
private String managerPass;
@Value("${ldap-${env}.server.url}")
private String url;
@Value("${ldap.password.attribute:userPassword}")
private String passwordAttr;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication().userDnPatterns("uid={0},ou=people").groupSearchBase("ou=groups")
.groupSearchFilter("(member={0})").userSearchBase("ou=people").userSearchFilter("(uid={0})")
.userDetailsContextMapper(new CustomLdapPersonContextMapper())
// .passwordCompare()
// .passwordAttribute(passwordAttr)
// .passwordEncoder(new PlaintextPasswordEncoder())
// .and()
.contextSource().managerDn(managerDn).managerPassword(managerPass).url(url);
}
}
}
但是,在某些情况下,用户可能会带着一个会话令牌进来,该令牌可以从会话密钥服务器进行身份验证,有效令牌返回一个用户名,然后可以使用该用户从LDAP加载Authridization信息。因此,我的第二个身份验证机制应该首先进行,如果会话令牌存在于http头中,则应该执行令牌身份验证,然后进行ldap查找,如果没有会话令牌,则应该使用当前的身份验证机制。如何添加第二层身份验证。
在使用纯java配置时,我花了相当多的时间来考虑Spring Security性。要使其发挥作用需要几个步骤。应该是沿着这条线的东西。基本流程如下:
>
创建自定义筛选器以检查特定授权信息的请求
每个筛选器返回null(如果未找到该类型的授权),或自定义AbstractAuthenticationToken
还要确保在过滤器的构造函数中设置ant匹配器,以控制过滤器应用的url模式。例如,ldap请求筛选器可能需要与任何请求“/*”一起检查,而用户名/密码筛选器只能在post的to/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;
}
}
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" ) );
}
}
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;
}
}
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();
}
}
问题内容: 当前,我的应用程序中只有一种身份验证机制,即使用LDAP进行身份验证和授权。我的安全配置如下所示 但是,在某些情况下,用户可能会带有可以从会话密钥服务器进行身份验证的会话令牌,而有效令牌会返回用户名,然后该用户名可用于从LDAP加载该用户的身份验证信息。因此,我的第二种身份验证机制应该首先发生,如果HTTP标头中存在会话令牌,则应执行令牌身份验证,然后进行ldap查找,如果不存在会话令
问题内容: 我想在我的Java应用程序中使用Windows NTLM认证来透明地认证Intranet用户。如果使用浏览器(单点登录),用户将不会注意到任何身份验证。 我发现了一些具有NTLM支持的库,但是不知道要使用哪个库: http://spnego.sourceforge.net/ http://sourceforge.net/projects/ntlmv2auth/ http://jcifs
我正在尝试配置一个具有多种身份验证机制(DB和LDAP)并使用Spring Security性作为其底层框架的应用程序。我正在使用java配置来设置Web和http安全性。我知道我们需要多个WebSecurityConfigurerAdapter实例来存储多个http元素(如基于xml的config中使用的);但是当我这样做时,应用程序只选择配置的第一个身份验证(数据库身份验证),并且从不使用第二
我有一个需要以两种不同方式保护的API: 1) 对除1以外的所有请求URL使用JWT,该URL需要使用基本身份验证进行保护 2) 一个url的基本身份验证。 我已经为JWT和Basic Auth设置了安全配置。我的问题是,当我使用有效的用户名和密码请求基本的经过身份验证的URL时,它会成功地对我进行身份验证,并将数据存储在cassandra中。 然后,我希望必须通过/api/login为所有其他请
问题内容: 在Spring Security中,有多个身份验证提供程序的参考,但是找不到Java config中的示例。 以下链接给出了XML表示法: Spring Security中的多个身份验证提供程序 我们需要使用LDAP或DB进行身份验证 下面是我们的示例代码: 问题答案: 也许这会帮助你:
问题内容: 我正在使用以下过滤器在我的Web应用程序中启用NTLM身份验证。 我得到Windows浏览器身份验证提示。运行正常。除了以下事实外- 我无法确定身份验证是成功还是失败! * 两种情况均无错误。 *在每种情况下都将打印用户名(正确或相反),工作站等。 web.xml很简单: 问题答案: 您收到的是Type 3消息,但是除了打印出详细信息之外,您什么都没做。此时,您需要验证客户的响应,并发