Spring security 如何通过ldap身份验证和授权对登录流应用安全性?
我用SpringWebflow2和SpringLDAP实现了一个登录servlet,用于用户身份验证。到目前为止一切正常 现在,我正在尝试在我的登录流中引入spring安全性。因此,遵循SpringWebFlowReferenceGuide版本2.4.0(第8节)和SpringSecurityLDAP部分指南,我调整了配置以保护流。特别是,我正在尝试为角色用户保护成功登录页面 我试图从ldap数据库中提取用户名、密码和用户角色,并使用这些信息在我的流中应用安全性。因此,我对我的项目进行了以下更改:Spring security 如何通过ldap身份验证和授权对登录流应用安全性?,spring-security,spring-ldap,spring-webflow-2,spring-security-ldap,Spring Security,Spring Ldap,Spring Webflow 2,Spring Security Ldap,我用SpringWebflow2和SpringLDAP实现了一个登录servlet,用于用户身份验证。到目前为止一切正常 现在,我正在尝试在我的登录流中引入spring安全性。因此,遵循SpringWebFlowReferenceGuide版本2.4.0(第8节)和SpringSecurityLDAP部分指南,我调整了配置以保护流。特别是,我正在尝试为角色用户保护成功登录页面 我试图从ldap数据库中提取用户名、密码和用户角色,并使用这些信息在我的流中应用安全性。因此,我对我的项目进行了以下更改
HTTP Status 500 - Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
________________________________________
type Exception report
message Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
root cause
org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
org.springframework.webflow.engine.impl.FlowExecutionImpl.wrap(FlowExecutionImpl.java:573)
org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:263)
org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:228)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
root cause
java.lang.NullPointerException
org.springframework.security.access.vote.RoleVoter.extractAuthorities(RoleVoter.java:115)
org.springframework.security.access.vote.RoleVoter.vote(RoleVoter.java:96)
org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62)
org.springframework.webflow.security.SecurityFlowExecutionListener.decide(SecurityFlowExecutionListener.java:109)
org.springframework.webflow.security.SecurityFlowExecutionListener.stateEntering(SecurityFlowExecutionListener.java:74)
org.springframework.webflow.engine.impl.FlowExecutionListeners.fireStateEntering(FlowExecutionListeners.java:144)
org.springframework.webflow.engine.impl.FlowExecutionImpl.setCurrentState(FlowExecutionImpl.java:373)
org.springframework.webflow.engine.impl.RequestControlContextImpl.setCurrentState(RequestControlContextImpl.java:189)
org.springframework.webflow.engine.State.enter(State.java:191)
org.springframework.webflow.engine.Transition.execute(Transition.java:228)
org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
org.springframework.webflow.engine.State.enter(State.java:194)
org.springframework.webflow.engine.Transition.execute(Transition.java:228)
org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
org.springframework.webflow.engine.ViewState.handleEvent(ViewState.java:231)
org.springframework.webflow.engine.ViewState.resume(ViewState.java:195)
org.springframework.webflow.engine.Flow.resume(Flow.java:537)
org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:228)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
我认为spring-config.xml中的身份验证提供程序设置与用于身份验证和授权的java类不匹配。如何从ldap中成功检索角色?我通过ldapAuthenticationManager注入解决了这个问题 我在spring config.xml身份验证管理器中添加了一个authManager别名和一个用于映射java类的属性:
...
<bean id="loginService" class="com.folkture.login.LoginService">
<property name="ldapTemplate" ref="ldapTemplate" />
<property name="ldapAuthenticationManager" ref="authManager" />
</bean>
...
<s:authentication-manager alias="authManager">
<s:ldap-authentication-provider
group-search-filter="(member={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="ROLE_"
user-search-filter="(cn={0})"
user-search-base="ou=users"
server-ref="contextSource" />
</s:authentication-manager>
...
并使用ldapAuthenticationManager更改了登录方法。Authentication方法:
public boolean login(String username, String password){
Authentication authenticatedUser = null;
Authentication auth = new UsernamePasswordAuthenticationToken(username, password);
authenticatedUser = ldapAuthenticationManager.authenticate(auth);
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
System.out.println("authenticatedUser role" + authenticatedUser.getAuthorities());
return true;
}
package com.folkture.login;
import javax.naming.directory.DirContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.AuthenticatedLdapEntryContextCallback;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapEntryIdentification;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.ldap.authentication.LdapAuthenticator;
import org.springframework.stereotype.Service;
@Service
public class LoginService implements LdapAuthenticator{
@Autowired
private LdapTemplate ldapTemplate;
public LoginService() {
super();
}
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
System.out.println("setLdapTemplate "+ ldapTemplate);
}
public String performLogin(LoginCredentials loginCredentials) throws Exception{
if(login(loginCredentials.getLoginName(),loginCredentials.getPassword()))
{
System.out.println("autenticato!");
return "success";
} else {
throw new IncorrectLoginCredentialsException();
}
}
public boolean login(String username, String password) throws Exception{
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "inetOrgPerson")).and(new EqualsFilter("cn", username));
if(ldapTemplate.authenticate("ou=users", filter.toString(), password, contextCallback))
return true;
return false;
}
AuthenticatedLdapEntryContextCallback contextCallback = new AuthenticatedLdapEntryContextCallback() {
@SuppressWarnings("deprecation")
public void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
try {
try {
ctx.lookup(ldapEntryIdentification.getRelativeDn());
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
}
catch (NamingException e) {
throw new RuntimeException("Failed to lookup " + ldapEntryIdentification.getRelativeDn(), e);
}
}
};
@Override
public DirContextOperations authenticate(Authentication authentication) {
// TODO Auto-generated method stub
return null;
}
}
HTTP Status 500 - Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
________________________________________
type Exception report
message Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
root cause
org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'performLoginAction' of flow 'loginFlow'
org.springframework.webflow.engine.impl.FlowExecutionImpl.wrap(FlowExecutionImpl.java:573)
org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:263)
org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:228)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
root cause
java.lang.NullPointerException
org.springframework.security.access.vote.RoleVoter.extractAuthorities(RoleVoter.java:115)
org.springframework.security.access.vote.RoleVoter.vote(RoleVoter.java:96)
org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62)
org.springframework.webflow.security.SecurityFlowExecutionListener.decide(SecurityFlowExecutionListener.java:109)
org.springframework.webflow.security.SecurityFlowExecutionListener.stateEntering(SecurityFlowExecutionListener.java:74)
org.springframework.webflow.engine.impl.FlowExecutionListeners.fireStateEntering(FlowExecutionListeners.java:144)
org.springframework.webflow.engine.impl.FlowExecutionImpl.setCurrentState(FlowExecutionImpl.java:373)
org.springframework.webflow.engine.impl.RequestControlContextImpl.setCurrentState(RequestControlContextImpl.java:189)
org.springframework.webflow.engine.State.enter(State.java:191)
org.springframework.webflow.engine.Transition.execute(Transition.java:228)
org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
org.springframework.webflow.engine.State.enter(State.java:194)
org.springframework.webflow.engine.Transition.execute(Transition.java:228)
org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
org.springframework.webflow.engine.ViewState.handleEvent(ViewState.java:231)
org.springframework.webflow.engine.ViewState.resume(ViewState.java:195)
org.springframework.webflow.engine.Flow.resume(Flow.java:537)
org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:228)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
...
<bean id="loginService" class="com.folkture.login.LoginService">
<property name="ldapTemplate" ref="ldapTemplate" />
<property name="ldapAuthenticationManager" ref="authManager" />
</bean>
...
<s:authentication-manager alias="authManager">
<s:ldap-authentication-provider
group-search-filter="(member={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="ROLE_"
user-search-filter="(cn={0})"
user-search-base="ou=users"
server-ref="contextSource" />
</s:authentication-manager>
...
...
@Autowired
@Qualifier("authManager")
private AuthenticationManager ldapAuthenticationManager;
public void setLdapAuthenticationManager(AuthenticationManager ldapAuthenticationManager) {
this.ldapAuthenticationManager = ldapAuthenticationManager;
}
public boolean login(String username, String password){
Authentication authenticatedUser = null;
Authentication auth = new UsernamePasswordAuthenticationToken(username, password);
authenticatedUser = ldapAuthenticationManager.authenticate(auth);
SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
System.out.println("authenticatedUser role" + authenticatedUser.getAuthorities());
return true;
}