我正在尝试将 spring security 集成到 spring mvc 中的现有代码库中。
在我现有的代码库中,我有一个 Web 项目中的客户端委托,它与服务项目中的服务委托交互,后者又与后端层的服务接口交互。它是我的后端层的服务接口实现m 实现 UserDetailsService 接口。
PS - 我正在跨所有层创建/转换/传递各种对象,即模型、DO、DTO、请求、响应等。
所以现在,当我点击提交时,我希望控件通过委托从 web 到后端层,直到实现 UserDetailsService 接口的类。我怎样才能做到这一点?
[更新]:通过此链接后,我更改了我的安全 xml,如下所示:
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/welcome.html" access="hasRole('ROLE_USER')" />
<security:form-login login-page="/portalLogin.html" login-processing-url="/signIn" always-use-default-target="true"
username-parameter="username" password-parameter="password"
default-target-url="/welcome.html" authentication-failure-url="/loginfailed.html" />
<security:logout logout-success-url="/logout.html" />
</security:http>
我的登录控制器是这样的:
@RequestMapping("/signIn")
public ModelAndView onClickLogin(@ModelAttribute("dashboard")
LoginModel loginModel,Model model){
try{
delegate.clickLogin(loginModel);
if(null != loginModel.getError()){
// return new ModelAndView("error");
}
}catch(Exception exception){
}
return new ModelAndView("redirect:welcome.html");
}
[更新]:很抱歉很晚更新。控制器映射问题已解决,现在由于 UsernamePasswordAuthenticationFilter 而我面临问题。在将上述代码生成的日志与正常工作的代码日志进行比较后,我发现 Spring Security 没有触发'UsernamePasswordAuthenticationFilter ' 在我的情况下出于某些原因。'UsernamePasswordAuthenticationFilter' 是对用户进行身份验证的一种。
//Logs when authentication is done
[while using spring's default /j_spring_security_check].
DEBUG FilterChainProxy - /j_spring_security_check at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG UsernamePasswordAuthenticationFilter - Request is to process authentication
DEBUG ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
session created
DEBUG SessionImpl - Opened session at timestamp: 13661947944
SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])
After openSession
DEBUG SessionImpl - Opened session at timestamp: 13661947944
Criteria before eq::this::CriteriaImpl(com.infy.itrade.core.entity.LoginDO:this[][])::CriteriaImpl(com.infy.itrade.core.entity.LoginDO:this[][])...
//Logs when authentication is not done [while using custom login processing url : /signIn.html].
DEBUG FilterChainProxy - /signIn.html at position 3 of 10 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter' //UsernamePasswordAuthenticationFilter is not doing authentication process instead it skips to next filter.
DEBUG FilterChainProxy - /signIn.html at position 4 of 10 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG FilterChainProxy - /signIn.html at position 5 of 10 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
我创建了一个自定义过滤器“MyFilter”,它扩展了“AbstractAuthenticationProcessingFilter”。但是 'MyFilter' 仍然没有进行任何身份验证,因为日志显示如下:
DEBUG FilterChainProxy - /signIn.html at position 2 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG FilterChainProxy - /signIn.html at position 3 of 9 in additional filter chain; firing Filter: 'MyFilter'
DEBUG FilterChainProxy - /signIn.html at position 4 of 9 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
我的过滤器:
public class MyFilter extends AbstractAuthenticationProcessingFilter {
private static final String DEFAULT_FILTER_PROCESSES_URL = "/signIn";
private static final String POST = "POST";
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
public MyFilter() {
super(DEFAULT_FILTER_PROCESSES_URL);
}
public MyFilter(String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
// TODO Auto-generated constructor stub
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse arg1) throws AuthenticationException,
IOException, ServletException {
// TODO Auto-generated method stub
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(
SPRING_SECURITY_LAST_USERNAME_KEY,
TextEscapeUtils.escapeEntities(username));
}
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
if (request.getMethod().equals(POST)) {
// If the incoming request is a POST, then we send it up
// to the AbstractAuthenticationProcessingFilter.
super.doFilter(request, response, chain);
} else {
// If it's a GET, we ignore this request and send it
// to the next filter in the chain. In this case, that
// pretty much means the request will hit the /login
// controller which will process the request to show the
// login page.
chain.doFilter(request, response);
}
}
...
}
上下文 xml:
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/portalLogin.html"/>
</bean>
<bean id="MyFilter" class="com.infosys.itrade.core.dao.security.MyFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="successHandler"></property>
<property name="authenticationFailureHandler" ref="failureHandler"></property>
<property name="filterProcessesUrl" value="/signIn"></property>
</bean>
<bean id="successHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/welcome.html" />
</bean>
<bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/loginfailed.html" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
user-service-ref="LoginUserDetailsService">
</security:authentication-provider>
</security:authentication-manager>
<bean id="LoginUserDetailsService"
class="com.infy.itrade.core.service.login.LoginServiceImpl">
<property name="logindao" ref="loginDAOImpl" />
</bean>
<bean id="loginDAOImpl" class="com.infy.itrade.core.dao.login.LoginDAODBImpl">
<property name="sessionFactory"> <ref bean ="sessionFactory"/> </property>
</bean>
</beans>
我在这里想念什么?
[更新]:由于我无法正常工作,因此我按照其他人的建议改变了我的方法,即我正在避免单独登录模块的架构流程。但现在我面临着新方法的不同问题,我会问一个不同的问题。谢谢。