Checking Spring security roles and logged username

2019-03-29 11:36发布

问题:

Does anyone know the freemarker tags to check spring security roles and username in freemarker file?

I found from couple of resources on the web that the following code would print the logged in username. But it is not printing the username, instead it is printing just "logged in as"

<security:authorize access="isAuthenticated()">
    logged in as <security:authentication property="principal.username" /> 
</security:authorize>

Also checking the roles in Freemarker file is also not working. Has anyone done it before?

回答1:

The following should work:
step 1: Include Spring security tag library on top of freemarker file
<#assign security=JspTaglibs["http://www.springframework.org/security/tags"] />

step 2: To check the role name

<@security.authorize ifAnyGranted="ROLE_USER">
    Your role is "ROLE_USER" <br/>
</@security.authorize>

Step 3: To check logged in user's loginname

<@security.authorize access="isAuthenticated()">
    logged in as <@security.authentication property="principal.username" /> 
</@security.authorize>

<@security.authorize access="! isAuthenticated()">
    Not logged in
</@security.authorize>

Hope this helps.



回答2:

I'm using a Maven/Jetty setup and the Spring Security Tags don't automatically get put into WEB-INF/lib. Therefore the following adjustments need to be made:

  1. Use the following assignment: <#assign security=JspTaglibs[ "/WEB-INF/security.tld" ]> or <#assign security=JspTaglibs[ "/security.tld" ]> depending on your web root.
  2. Very ugly: copy security.tld from the spring-security-taglibs jar into WEB-INF. Unfortunately I was unable to get Freemarker to resolve the tag lib from the classpath.


回答3:

You can create an HandlerInterceptor that can inject the user in context:

public class PutUserInModelInterceptor implements HandlerInterceptor {

  @Override
  public boolean preHandle(HttpServletRequest aRequest, HttpServletResponse aResponse, Object aHandler) throws Exception {
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest aRequest, HttpServletResponse aResponse, Object aHandler, ModelAndView aModelAndView) throws Exception {
    if(aModelAndView != null) {
      Principal user = aRequest.getUserPrincipal();
      aModelAndView.addObject("__user", user);
    }
  }

  @Override
  public void afterCompletion(HttpServletRequest aRequest, HttpServletResponse aResponse, Object aHandler, Exception aEx) throws Exception { }

}

And then register it:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new PutUserInModelInterceptor());
  }

}

And then use it in your template. e.g:

<#if !(__user??)> 
  <a class="p-2" href="#" data-toggle="modal" data-target="#signinModal">Sign in</a>
<#else>
  <span class="badge badge-secondary">${__user.getName()}</span>
</#if>