Spring 3 добавление UserDetails в сессию - PullRequest
0 голосов
/ 21 февраля 2012

Я пытаюсь реализовать настройку входа пользователя в систему с помощью БД в Spring 3. Мои журналы показывают, что пользователь прошел аутентификацию нормально, используя имя пользователя / имя пользователя, указанное в форме входа, но пользователь, кажется, не доступен вJSP с тех пор, как пользователи перестали жестко программировать в конфигурации.

Такое ощущение, что объект UserDetails по какой-то причине недоступен через session / securitycontext.

В моем файле security-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>

Фрагмент из моей службы пользователя (который реализует интерфейс 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);// System.out.println ("** Пользователь LoginController подтвержден нормально:" + context.getAuthentication (). GetName ());// System.out.println ("** Принцип LoginController:" + 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 / Spring MVC.Если кто-то может предложить какой-то фундаментальный аспект инфраструктуры аутентификации Spring, который мне не хватает, было бы замечательно!

Followup / EDIT: я попытался вернуться к стилю формы, предложенному @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, я получаю исключение NullPointerException в Hibernate sessionFactory, оказывается, что ни SessionFactory, ни моя другая служба не вводятся так, как я ожидал.

Компонент sessionFactory, который должен быть внедрен, определен в моем hibernate-context.xml, который включен через оператор импорта в мою конфигурацию servlet.xml.Однако поставщик аутентификации объявлен в security-context.xml, который не ссылается на hibernate-context.xml.Поэтому я скопировал оператор импорта в контекст безопасности в надежде, что это решит проблему внедрения / создания экземпляра, но это тоже не поможет.

1 Ответ

1 голос
/ 21 февраля 2012

Я думаю, ты делаешь это более сложным, чем нужно, весна делает всю работу за тебя. Вам не нужно писать контроллер для отправки формы входа. Используйте spring_secruity_login так:

<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, импорт:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

Затем отобразите (или используйте getAuthorities для доступа к ролям):

Username is  <sec:authentication property="principal.username" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...