首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring 3将UserDetails添加到会话

Spring 3将UserDetails添加到会话
EN

Stack Overflow用户
提问于 2012-02-21 20:27:11
回答 1查看 3.4K关注 0票数 0

我正在尝试用Spring3实现一个数据库驱动的用户登录设置。我的日志显示,用户使用登录表单中提供的用户名/密码进行了身份验证,但在JSP中似乎无法访问用户,因为不再将用户硬编码到config中。

由于某些原因,UserDetails对象似乎不能通过会话/安全上下文使用。

在我的security-config.xml中:旧的硬编码样式...

代码语言:javascript
复制
    <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>

新身份验证提供程序...

代码语言:javascript
复制
<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <!-- 
        <password-encoder ref="pwdEncoder" >
            <salt-source ref="saltSource"/>
        </password-encoder>
         -->
    </authentication-provider>
</authentication-manager>

来自我的用户服务(它实现了Spring UserDetailsService接口)的代码片段:

代码语言:javascript
复制
    @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上:

代码语言:javascript
复制
    @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);// System.out.println("** LoginController user validated ok:"+context.getAuthentication().getName());// System.out.println("** LoginController principle:"+context.getAuthentication().getPrincipal());} else { return loginError(model);}

代码语言:javascript
复制
    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中包装在安全标记中的任何内容都不会显示。例如,在以管理员用户身份成功登录后,缺少此块:

代码语言:javascript
复制
        <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/Spring MVC的新手。如果有人能给我一些Spring身份验证框架的基本方面的建议,那就太好了!

关注/编辑:我尝试恢复到@NimChimpsky在评论中建议的表单样式。我在身份验证提供程序的设置中有两个选项,第一个是有效的:

代码语言:javascript
复制
<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>

第二个,不是:

代码语言:javascript
复制
<beans:bean id="userService" class="uk.co.romar.guardian.services.UserServiceImpl" />

。。

当我尝试使用UserServiceImpl类进行身份验证时,我在Hibernate sessionFactory上得到了一个NullPointerException,结果发现SessionFactory或我的其他服务都没有像我预期的那样被注入。

应该被注入的hibernate bean是在我的sessionFactory -context.xml中定义的,它是通过我的servlet.xml配置中的import语句包含的。但是,身份验证提供程序是在security-context.xml中声明的,它没有引用hibernate-context.xml。因此,我将import语句复制到security-context中,希望这样可以解决注入/实例化问题,但这也没有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-21 20:30:56

我认为你把它弄得太复杂了,spring为你做了所有的腿部工作。您不必编写用于提交登录表单的控制器。像这样使用spring_secruity_login:

代码语言:javascript
复制
<form name="f" id="f" action="<c:url value='j_spring_security_check'/>" method="POST">
  <label for="username">Username :&nbsp;</label>
  <input type='text' id='j_username' name='j_username'/><br>
  <label for="password">Password :&nbsp;</label>
  <input type='password' id='j_password' name='j_password'><br>

登录后(只需提交上面的表单,您就可以访问jsp中的主体,import:

代码语言:javascript
复制
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

然后显示(或使用getAuthorities访问角色):

代码语言:javascript
复制
Username is  <sec:authentication property="principal.username" />
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9377619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档