[英]can't login after I have switched from in memory data store to using a database in spring security
I am trying to use Spring security for my web application. 我正在尝试为我的Web应用程序使用Spring安全性。 I am about to make a login feature, so users can login to secured pages in my website.
我即将启用登录功能,因此用户可以登录到我网站中的安全页面。 So far I have been using Spring security's own , where I have used an in-memory data store for authentication (mostly to test if it worked, since I am still learning.)
到目前为止,我一直在使用Spring security自己的系统,在这里我使用内存中的数据存储进行身份验证(主要是测试它是否有效,因为我仍在学习。)
My problem occurs, when I am trying to use my database where I have stored different Users. 当我尝试使用存储不同用户的数据库时,出现了我的问题。 When I am trying to log in, spring security redirects me to my 'authentication-failure-url', instead of logging me in.
当我尝试登录时,Spring Security会将我重定向到“ authentication-failure-url”,而不是登录。
I have created a custom UserDetails class 我创建了一个自定义UserDetails类
package dk.chakula.web.security;
import dk.chakula.web.domain.User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
/**
*
* @author Martin Rohwedder
* @since 20-02-2013
* @version 1.0
*/
public class ChakulaUserDetails implements UserDetails {
private User user;
private List<? extends GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
public ChakulaUserDetails(User user, List<? extends GrantedAuthority> authorities) {
this.user = user;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return this.user.getPassword();
}
@Override
public String getUsername() {
return this.user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
I have also created a custom UserDetailsService, which my 'authentication-provider' is referencing. 我还创建了一个自定义UserDetailsService,我的“身份验证提供程序”正在引用它。 That class looks like this.
那堂课看起来像这样。
package dk.chakula.web.security;
import dk.chakula.web.domain.User;
import dk.chakula.web.service.UserService;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
/**
*
* @author Martin Rohwedder
* @since 20-02-2013
* @version 1.0
*/
@Component("chakulaUserDetailsService")
public class ChakulaUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (StringUtils.isBlank(username)) {
throw new UsernameNotFoundException("Username was empty");
}
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User with username '" + username + "' was not found");
}
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new SimpleGrantedAuthority(user.getUserRole()));
return new ChakulaUserDetails(user, grantedAuthorities);
}
}
My full spring security context looks like this 我整个春季安全上下文看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http use-expressions="true">
<!-- Form Login Filter -->
<security:form-login login-page="/login" default-target-url="/app/start" authentication-failure-url="/login?authenticationNok=1" username-parameter="username" password-parameter="password" always-use-default-target="true" />
<!-- Logout Filter -->
<security:logout logout-success-url="/home?logoutOk=1" logout-url="/logout" invalidate-session="true" />
<!-- Intercept Url filters -->
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/home" access="permitAll" />
<security:intercept-url pattern="/about" access="permitAll" />
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/app/**" access="fullyAuthenticated" />
</security:http>
<bean id="chakulaUserDetailsService" class="dk.chakula.web.security.ChakulaUserDetailsService" />
<security:authentication-manager>
<security:authentication-provider user-service-ref="chakulaUserDetailsService">
<security:password-encoder hash="sha-256">
<security:salt-source user-property="username" />
</security:password-encoder>
<!--
<security:user-service>
<security:user name="test" password="e9233bd61e14137a7e28f92c50ce279215e774a1772d1e9dad5f275b9cc8177c" authorities="ROLE_CUSTOMER" />
</security:user-service>
-->
</security:authentication-provider>
</security:authentication-manager>
</beans>
You can get a look at all the source code at my Chakula project on GITHUB, if you need this to help me - https://github.com/martin-rohwedder/chakula 如果您需要帮助,可以查看我在GITHUB上Chakula项目中的所有源代码-https: //github.com/martin-rohwedder/chakula
It all seemed to be a failure with my Dao Implementation class, because when I showed the message of the AuthenticationException it told me the following - could not resolve property: USERNAME of: dk.chakula.web.domain.User [from dk.chakula.web.domain.User u where u.USERNAME = :USERNAME] 我的Dao Implementation类似乎全部失败,因为当我显示AuthenticationException消息时,它告诉我以下内容-无法解析属性:USERNAME of:dk.chakula.web.domain.User [来自dk.chakula .web.domain.User u,其中u.USERNAME =:USERNAME]
All I had to do was to write u.USERNAME with non capital letters. 我要做的就是用非大写字母写u.USERNAME。
I rewrited my security context xml files form-login tags authentication-failure-url attribute with the following value instead. 我改用以下值重写了安全上下文xml文件的form-login标签authentication-failure-url属性。
<security:form-login login-page="/login" default-target-url="/app/start" authentication-failure-url="/login/failure" username-parameter="username" password-parameter="password" always-use-default-target="true" />
Thereafter I had in my AuthenticationController made a new method to render the failure view, and add the AuthenticationException message as a model to the view 之后,我在AuthenticationController中制作了一个新方法来呈现故障视图,并将AuthenticationException消息作为模型添加到视图中
@RequestMapping(value = {"/login/failure"}, method = RequestMethod.GET)
public ModelAndView renderLoginFailureView(HttpServletRequest request) {
ModelAndView mav = new ModelAndView("login");
AuthenticationException authEx = (AuthenticationException) request.getSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
mav.addObject("authEx", authEx.getMessage());
return mav;
}
Next time I know to show all exception messages before rushing in to stackoverflow. 下次我知道在赶赴stackoverflow之前先显示所有异常消息。 Though now others maybe can benefit on my answer in the future.
尽管现在其他人将来可能会从我的回答中受益。
Thanks to Arun P Johny for helping me out here. 感谢Arun P Johny在这里帮助我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.