【问题标题】:Spring security access UserDetailsService from deeper layersSpring安全从更深层次访问UserDetailsS​​ervice
【发布时间】:2011-06-22 05:49:44
【问题描述】:


我有以下 UserDetailsS​​ervice 实现。
到目前为止,身份验证过程运行良好。
如何将我的“MyUser bean”(成功登录)存储在“会话”中,以便我可以在应用程序的其他区域访问它

谢谢。

@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {


    private EmployeesApi employeesApi = new EmployeesApi();

    /**
     * Retrieves a user record containing the user's credentials and access. 
     */
    public UserDetails loadUserByUsername(String userName)
            throws UsernameNotFoundException, DataAccessException {

        // Declare a null Spring User
        UserDetails user = null;

        try {


            MyUser employee = employeesApi.getByUserName(userName);



            user =  new User(
                    employee.getUserName(), 
                    employee.getPassword().toLowerCase(),
                    true,
                    true,
                    true,
                    true,
                    getAuthorities(1) );

        } catch (Exception e) {
            logger.error("Error in retrieving user");
            throw new UsernameNotFoundException("Error in retrieving user");
        }


    }
    ....

【问题讨论】:

    标签: java spring-mvc spring-security


    【解决方案1】:

    Spring Security 已经在会话中为您存储了经过身份验证的用户的 UserDetails。

    因此,在会话中存储MyUser 的最简单方法是实现一个自定义UserDetails,其中包含对MyUser 的引用:

    public class MyUserDetails extends User {
        private MyUser myUser;
        public MyUserDetails(..., MyUser myUser) {
            super(...);
            this.myUser = myUser;
        }
        public MyUser getMyUser() {
            return myUser;
        }
        ...
    }
    

    然后从你的UserDetailsService返回它:

    MyUser employee = employeesApi.getByUserName(userName);
    user =  new MyUserDetails(..., myUser);
    

    然后您可以通过安全上下文轻松访问MyUser:

    MyUser myUser = ((MyUserDetails) SecurityContextHolder
        .getContext().getAuthentication().getPrincipal()).getMyUser();
    

    在 Spring MVC 控制器中:

    @RequestMapping(...)
    public ModelAndView someController(..., Authentication auth) {
        MyUser myUser = ((MyUserDetails) auth.getPrincipal()).getMyUser();
        ...
    }
    

    在 JSP 中:

    <security:authentication var = "myUser" property="principal.myUser" />
    

    【讨论】:

    • 对不起,我不明白,你能发布简单的例子吗?德克萨斯州!
    • 而且,当我进入 loadUserByUsername 时,我还不知道登录是否成功。所以我无法决定是否存储它。德克萨斯州!
    • @fatnjazzy:您不需要手动存储它。 Spring Security 会在认证成功后自动存储UserDetails。
    • 谢谢,这行得通,但我有一个问题,将MyUser myUser = ((MyUserDetails) auth.getPrincipal()).getMyUser(); 存储在静态方法中会影响整个应用程序,允许其他层访问它的最佳方法是什么? (我会点击“V”)
    • 算了,我是从SecurityContextHolder.getContext().getAuthentication().getPrincipal()得到的,谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 2011-09-01
    相关资源
    最近更新 更多