我试图用Spring 3实现数据库驱动的用户登录设置。 我的日志显示用户使用登录表单中提供的用户名/密码进行了身份验证,但用户doesn由于不想将用户硬编码到配置中,因此似乎无法在JSP中访问。Spring 3将UserDetails添加到会话
感觉就像UserDetails对象由于某种原因通过session/securitycontext不可用。
在我的安全-config.xml中: 老硬编码风格。
<authentication-provider>
<user-service>
<user name="reports" password="reports" authorities="ROLE_REPORTS" />
<user name="admin" password="admin" authorities="ROLE_REPORTS, ROLE_ADMIN" />
<user name="super" password="super" authorities="ROLE_REPORTS, ROLE_ADMIN, ROLE_SUPER_ADMIN"/>
</user-service>
</authentication-provider>
新的身份验证提供者...
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userService">
<!--
<password-encoder ref="pwdEncoder" >
<salt-source ref="saltSource"/>
</password-encoder>
-->
</authentication-provider>
</authentication-manager>
片段从我userservice(它实现了Spring的UserDetailsService接口):
@Transactional
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
DbUser dbUser = null;
List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
Session sess = sessionFactory.getCurrentSession();
Query query = sess.createQuery("from DbUser where userName = '"+userName+"'");
Iterator<Object> it = query.iterate();
if(it.hasNext()) {
if(it.hasNext()) {
dbUser = (DbUser) it.next();
}
}
if (dbUser == null) {
throw new UsernameNotFoundException("user not found");
} else {
for (GrantedAuthority auth : dbUser.getRoles()) {
roles.add(new Role(auth.getAuthority()));
}
}
UserDetails springUser = null;
springUser = new org.springframework.security.core.userdetails.User(
dbUser.getUserName(),
dbUser.getPassword().toLowerCase(),
dbUser.getActive(),
true, true, true,
roles);
return springUser;
}
从我的loginController:
@RequestMapping(value="/login/submit", method=RequestMethod.POST)
public String login(Principal principle, HttpServletRequest request, ModelMap model){
String username = request.getParameter("username");
String password = request.getParameter("password");
UserDetails springUser = null;
try {
springUser = userService.loadUserByUsername(username);
} catch(UsernameNotFoundException e) {
e.printStackTrace();
model.addAttribute("message","User not found");
return loginError(model);
}
if(springUser.getPassword().equals(password)){ // user/pwd combo is correct
/**
* @todo make sure user ends up as the session user here
*/
// SecurityContext context = SecurityContextHolder.getContext(); // //context.setAuthentication(springUser); (“** LoginController user validated ok:”+ context.getAuthentication()。getName()); (“** LoginController principle:”+ context.getAuthentication()。getPrincipal()); } else { return loginError(model); }
Collection<GrantedAuthority> roles = springUser.getAuthorities();
for(GrantedAuthority auth : roles){
if(auth.getAuthority().equals(Role.ROLE_ADMIN)){
return "admin/home";
}
}
model.addAttribute("message", "Logged in");
return "reports/summaries";
}
你会在我的控制器上面,我想我会希望能够访问一个UserDetails在会话对象中看到的,但是任何记录有只返回字符串“anonymousUser”。
报告/摘要jsp显示正常,除了任何数据。没有显示包含在安全性标签中的JSP中的任何内容。 如后显然登录成功作为管理员用户缺少此块:
<sec:authorize access="hasRole('ROLE_ADMIN')">
<li>
<a href="<c:url value="/admin/home"/>">Admin</a>
<ul>
<li><a href="<c:url value="/admin/form/checkpoints"/>">Checkpoints</a></li>
<li><a href="<c:url value="/admin/form/guards"/>">Guards</a></li>
<li><a href="<c:url value="/admin/form/incidents"/>">Incidents</a></li>
<li><a href="<c:url value="/admin/form/routes"/>">Routes</a></li>
</ul>
</li>
</sec:authorize>
正如你可能已经云集,我是新来春/ Spring MVC的。如果任何人都可以建议Spring认证框架的一些基本方面,我错过了这将是伟大的!
后续/编辑: 我试着恢复到@NimChimpsky在评论中建议的表单样式。我在设置2个选项进行身份验证提供者,第一,它的工作原理:
<authentication-provider>
<user-service>
<user name="reports" password="reports" authorities="ROLE_REPORTS" />
<user name="admin" password="admin" authorities="ROLE_REPORTS, ROLE_ADMIN" />
<user name="super" password="super" authorities="ROLE_REPORTS, ROLE_ADMIN, ROLE_SUPER_ADMIN"/>
</user-service>
</authentication-provider>
第二,这不:
<beans:bean id="userService" class="uk.co.romar.guardian.services.UserServiceImpl" />
..
当我尝试使用该UserServiceImpl类进行身份验证我在Hibernate sessionFactory上得到NullPointerException,事实证明SessionFactory或我的其他服务都没有按照我的预期注入。
应该注入的sessionFactory bean在我的hibernate-context.xml中定义,它通过我的servlet.xml配置中的import语句包含。然而,身份验证提供程序在security-context.xml中声明,它不引用hibernate-context.xml。所以我将import语句复制到安全上下文中,希望能够对注入/实例化问题进行排序,但这也没有帮助。
感谢@NimChimpsky,我用的是形式的无控制器的风格加上我的用户服务之前,我认为控制器得到了补充阅读各种教程后,我得到。现在有一个不同的问题(SessionFactory没有被注入到用户服务中,我认为这不是相关的),当我已经排序,我会尝试返回到这种形式 – DaFoot 2012-02-21 13:45:55
添加上下文:组件扫描到我的安全维护似乎已经通过注射排序了其他问题。其他问题,但我会提出新的问题。 – DaFoot 2012-02-21 17:40:48