Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring 3 adding UserDetails to session
    primarykey
    data
    text
    <p>I'm trying to implement a DB driven user login setup with Spring 3. My logs show me the user was authenticated ok using the username/apssword provided in the login form, but the user doesn't seem to be accessible in JSPs since moving away from having the users hardcoded into config.</p> <p>It feels like the UserDetails object isn't available through the session/securitycontext for some reason. </p> <p>In my security-config.xml: Old hardcoded style...</p> <pre><code> &lt;authentication-provider&gt; &lt;user-service&gt; &lt;user name="reports" password="reports" authorities="ROLE_REPORTS" /&gt; &lt;user name="admin" password="admin" authorities="ROLE_REPORTS, ROLE_ADMIN" /&gt; &lt;user name="super" password="super" authorities="ROLE_REPORTS, ROLE_ADMIN, ROLE_SUPER_ADMIN"/&gt; &lt;/user-service&gt; &lt;/authentication-provider&gt; </code></pre> <p>New auth-provider...</p> <pre><code>&lt;authentication-manager alias="authenticationManager"&gt; &lt;authentication-provider user-service-ref="userService"&gt; &lt;!-- &lt;password-encoder ref="pwdEncoder" &gt; &lt;salt-source ref="saltSource"/&gt; &lt;/password-encoder&gt; --&gt; &lt;/authentication-provider&gt; &lt;/authentication-manager&gt; </code></pre> <p>Snippet from my userservice (which implements the Spring UserDetailsService interface):</p> <pre><code> @Transactional public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException { DbUser dbUser = null; List&lt;GrantedAuthority&gt; roles = new ArrayList&lt;GrantedAuthority&gt;(); Session sess = sessionFactory.getCurrentSession(); Query query = sess.createQuery("from DbUser where userName = '"+userName+"'"); Iterator&lt;Object&gt; 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; } </code></pre> <p>From my loginController:</p> <pre><code> @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 */ </code></pre> <p>// 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); }</p> <pre><code> Collection&lt;GrantedAuthority&gt; 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"; } </code></pre> <p>You'll see in my controller above where I think I would expect to be able to access a UserDetails object in the session, however any logging there only returns the string "anonymousUser".</p> <p>The reports/summaries jsp is displayed ok, except for any data. Anything in the JSP that is wrapped in security tags doesn't get displayed. eg missing this chunk after apparently logging in successfully as an admin user:</p> <pre><code> &lt;sec:authorize access="hasRole('ROLE_ADMIN')"&gt; &lt;li&gt; &lt;a href="&lt;c:url value="/admin/home"/&gt;"&gt;Admin&lt;/a&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="&lt;c:url value="/admin/form/checkpoints"/&gt;"&gt;Checkpoints&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="&lt;c:url value="/admin/form/guards"/&gt;"&gt;Guards&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="&lt;c:url value="/admin/form/incidents"/&gt;"&gt;Incidents&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="&lt;c:url value="/admin/form/routes"/&gt;"&gt;Routes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/sec:authorize&gt; </code></pre> <p>As you've probably gathered by now, I'm new to Spring/Spring MVC. If anyone can suggest some fundamental aspect of Spring authentication framework I'm missing that would be great!</p> <p>Followup/EDIT: I've tried reverting back to the form style suggested by @NimChimpsky in comments. I have 2 options in settings for authentication-provider, the first, which works :</p> <pre><code>&lt;authentication-provider&gt; &lt;user-service&gt; &lt;user name="reports" password="reports" authorities="ROLE_REPORTS" /&gt; &lt;user name="admin" password="admin" authorities="ROLE_REPORTS, ROLE_ADMIN" /&gt; &lt;user name="super" password="super" authorities="ROLE_REPORTS, ROLE_ADMIN, ROLE_SUPER_ADMIN"/&gt; &lt;/user-service&gt; &lt;/authentication-provider&gt; </code></pre> <p>The second, which doesn't:</p> <pre><code>&lt;beans:bean id="userService" class="uk.co.romar.guardian.services.UserServiceImpl" /&gt; </code></pre> <p>.. <br> </p> <p>When I attempt to authenticate using that UserServiceImpl class I was getting a NullPointerException on the Hibernate sessionFactory, it turns out neither the SessionFactory or my other service are getting injected as I expected. </p> <p>The sessionFactory bean that should get injected is defined in my hibernate-context.xml, which is included via an import statement in my servlet.xml config. The authentication-provider however is declared in security-context.xml which does not reference hibernate-context.xml. So I copied the import statement into security-context in the hope that would sort the injection/instantiation issue, but that doesn't help either.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload