Spring Security 2.0.6 调用 UserDetailService 的 loadUserByName 方法
我正在构建一个简单的 Sring MVC 应用程序。现在我正在尝试添加 Spring 安全性。我添加了一个 customUserDetailsService
,它使用 DAO 访问 MySql 数据库并获取用户。
@Transactional(readOnly = true)
public class CustomUserDetailService implements UserDetailsService {
@EJB(name = "UserDAOLocal")
UserDAOLocal dao = null;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
System.out.println("Checking if this is invoked")
UserDetails user = null;
DBUsers dbUser = dao.findUserName(username);
user = new User(dbUser.getUserName(), dbUser.getPassword(), true, true, true, true, getAuthorities(dbUser.getAccess()));
return user;
}
private GrantedAuthority[] getAuthorities(Integer access) {
GrantedAuthority[] authList = new GrantedAuthority[2];
authList[0] = new GrantedAuthorityImpl("ROLE_USER");
if (access.compareTo(1) == 0) {
authList[1] = new GrantedAuthorityImpl(("ROLE_ADMIN"));
}
return authList;
}
}
我已将 UserDetailsService
添加到 Spring-security.xml
中。
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService"/>
</security:authentication-manager>
<bean id="customUserDetailsService" class="service.CustomUserDetailService"/>
我将 j_spring_security_check
作为 login.jsp
页面上登录表单的操作。
当我输入有效的用户名和密码时,应用程序总是告诉我这是错误的。更重要的是,我找不到任何证据表明 customUserDetailsService
正在随时运行。 (我使用 System.out.println("Checking if this is invoked") 来检查服务器)。
什么会调用 CustomUserDetailsService
的 loadUserByUsername()
方法?什么时候调用它?
我该如何配置它?
(我提供的所有代码可能都是不必要的:))
编辑: 这是 Spring-Security.xml 的其余部分,
<security:http auto-config="true">
<security:intercept-url pattern="/AddEmployee.htm" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/FireEmployee.htm" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/employees.htm" access="ROLE_USER"/>
<security:form-login login-page="/login.htm"
authentication-failure-url="/login.htm?error=true"
login-processing-url="/j_spring_security_check.htm"
default-target-url="/common.htm"/>
<security:logout
invalidate-session="true"
logout-success-url="/login.htm"
logout-url="/logout.htm"/>
</security:http>
我通过像这样编辑身份验证提供程序来解决该问题。我决定不使用DAO和用户数据库。并在 xml 文件中使用硬编码用户,
<security:authentication-provider>
<security:user-service>
<security:user name="sam" password="sam123" authorities="ROLE_ADMIN,ROLE_USER" />
<security:user name="pam" password="pam123" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
这非常有效。
但我想知道为什么我的customUserDetailService从未被使用过,并学习如何正确使用它。
I'm building a simple Sring MVC app. And now i'm trying to add Spring security. I've added a customUserDetailsService
that uses a DAO to access a MySql database and get users.
@Transactional(readOnly = true)
public class CustomUserDetailService implements UserDetailsService {
@EJB(name = "UserDAOLocal")
UserDAOLocal dao = null;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
System.out.println("Checking if this is invoked")
UserDetails user = null;
DBUsers dbUser = dao.findUserName(username);
user = new User(dbUser.getUserName(), dbUser.getPassword(), true, true, true, true, getAuthorities(dbUser.getAccess()));
return user;
}
private GrantedAuthority[] getAuthorities(Integer access) {
GrantedAuthority[] authList = new GrantedAuthority[2];
authList[0] = new GrantedAuthorityImpl("ROLE_USER");
if (access.compareTo(1) == 0) {
authList[1] = new GrantedAuthorityImpl(("ROLE_ADMIN"));
}
return authList;
}
}
And i've added the UserDetailsService
to the Spring-security.xml
.
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService"/>
</security:authentication-manager>
<bean id="customUserDetailsService" class="service.CustomUserDetailService"/>
I put j_spring_security_check
as the action to the login form on the login.jsp
page.
When i enter a valid username and a password the app always tells it's wrong. What's more is i can't find any evidence that the customUserDetailsService
is running at anytime. (I used System.out.println("Checking if this is invoked")
to check on the server).
What invokes the loadUserByUsername()
method of the CustomUserDetailsService
? When is it invoked?
How can i configure it?
(All the codes i supplied might be unnecessary :))
EDIT:
Here is the rest of the Spring-Security.xml
<security:http auto-config="true">
<security:intercept-url pattern="/AddEmployee.htm" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/FireEmployee.htm" access="ROLE_ADMIN"/>
<security:intercept-url pattern="/employees.htm" access="ROLE_USER"/>
<security:form-login login-page="/login.htm"
authentication-failure-url="/login.htm?error=true"
login-processing-url="/j_spring_security_check.htm"
default-target-url="/common.htm"/>
<security:logout
invalidate-session="true"
logout-success-url="/login.htm"
logout-url="/logout.htm"/>
</security:http>
I worked around the problem by editing the authentication provider like this. I decided not use DAO, and user database. and used hard coded users inside the xml file
<security:authentication-provider>
<security:user-service>
<security:user name="sam" password="sam123" authorities="ROLE_ADMIN,ROLE_USER" />
<security:user name="pam" password="pam123" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
This works perfectly.
But i would like to know why my customUserDetailService was never used, And learn how to use it correctly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
分享更多配置。 Spring-security.xml 中的内容会有所帮助(如果可能)
Spring security 的设计使您的身份验证提供程序调用返回 userDetails 对象的
UserDetailsService
的loadUserByUsername()
方法。流程如下:
身份验证管理器的任务是对用户进行身份验证。因此它将用户名发送到
身份验证提供程序
。Authentication Provider
调用loadUserByUsername()
方法并传递 String 类型的用户名,该用户名返回userDetails
对象。现在,这个
userDetails
对象包含了身份验证所需的所有信息,例如用户名、密码、isEnabled 等。现在,如果您想自定义
userDetailsService
以使用您的Dao
,您可以自定义它。这就是您的身份验证过程的工作原理。
您可以参考此<强>链接以获得更广泛的理解。
Sharing more config. from Spring-security.xml would help(if possible)
Spring security is Designed so that your Authentication provider calls
loadUserByUsername()
method of theUserDetailsService
which returns userDetails Object.Process is as follows:
Task of
Authentication Manager
is to Authenticate the user. So it sends the user name toAuthentication provider
.Authentication Provider
callsloadUserByUsername()
method and passes user name of type String which returnsuserDetails
Object.Now this
userDetails
object contains all necessary information for authentication, such as username, password, isEnabled etc.Now if you want to customize
userDetailsService
for using yourDao
you can customize it.This is how your authentication process works.
You can refer this link for broader understanding.