简体   繁体   中英

How to display current logged-in user's information in all templates including view managed by WebMvcConfigurerAdapter in Spring Security application

I have a Spring Boot application that uses Spring Security and Thymeleaf template. I am trying to display the logged-in user's first name and last name in a template when the controller is managed by a subclass of WebConfigurerAdapter.

So, say my WebConfigurerAdapter subclass looks like this

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void addViewControllers(ViewControllerRegistry registry){
        registry.addViewController("/some-logged-in-page").setViewName("some-logged-in-page");
        registry.addViewController("/login").setViewName("login");

    }
    ....
}

My User entity class looks like this

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Long id;



    @Column(name="first_name", nullable = false)
    private String firstName;


    public String getFirstName() {
        return firstName;
    }
    ...
}

In my template, I have tried using code like

<div sec:authentication="firstName"></div> 

But it didn't work.

I know it is possible to use a ControllerAdvise as follows:

@ControllerAdvice
public class CurrentUserControllerAdvice {
    @ModelAttribute("currentUser")
    public UserDetails getCurrentUser(Authentication authentication) {
        return (authentication == null) ? null : (UserDetails) authentication.getPrincipal();
    }
}

and then access the details in the template using code like:

<span th:text ="${currentUser.getUser().getFirstName()}"></span>

But this doesn't work with any view controller registered with my class MvcConfig. Rather I will need to make sure each of my controllers are separate classes.

So, could someone kindly point me to a way to automatically insert the logged-in user details to my view, eg some-logged-in-page.html in this example? Thanks

It's quite easy to accomplish this, thanks to a hint from Balaji Krishnan.

Basically, I had to add the Thymeleaf Spring Security integration module to my build.gradle file as follows:

compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity3")

Then in my template I just used the following markup:

<span th:text ="${#authentication.getPrincipal().getUser().getFirstName()}"></span>

使用 Spring Security 4 和 Thymeleaf 3 时:

<span th:text="${#authentication.getPrincipal().getUsername()}"></span>

When using Spring boot 2.2.1.

For the maven, Add these lines to the pom.xml

<dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>

In the thymeleaf

<span th:text="${#authentication.getPrincipal().getUsername()}"></span> <span th:text="${#authentication.getPrincipal().authorities}"></span>

This construct is working for me (spring boot 1.5 and 2.0/thymeleaf 3):
It is documented here (bottom of the page) Thymeleaf + Spring Security integration basics

Logged user: <span sec:authentication="name">Bob</span>

Don´t forget to include the sec tag in the html section of your view:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
</head>
<body>

I hope this helps!
Have a nice day!
Thomas

As @B378 said, When using Spring Security 4 and Thymeleaf 3: you have to use following.

<span th:text="${#authentication.getPrincipal().getUsername()}"></span>

Because spring security uses UserDetails internally. And UserDetails contains one function called getUsername().

For me, When using Spring boot 2.1.2 I need to use the following

<span th:text="${#authentication.getPrincipal()}"></span> <!-- No ".getUsername()"-->

With thymeleaf-extras-springsecurity5

This page was useful. Thanks for all the replies. Please note that if you are using the latest Spring Boot ie version 2.1.0 then you need to use the following: thymeleaf-extras-springsecurity5

LINK

For thymleaf 4 and above you have to modify some classes in order to get the info. Heres how you can do that:

First, add the getter of your user getUser(){return this.user;} in the UserDetails class and then push that object in the UserDetailsService object. Without these changes, thymleaf will not parse your HTML file.

Then you can get the info as follows:

<span sec:authentication="principal.user.name">

Don't forget to check if a user is authenticated before trying to print his detais

<th:block th:if="${#authorization.expression('isAuthenticated()')}">
                    <span>Hello</span>
                    <span th:text="${#authentication.getPrincipal().getFullName()}"></span>
                </th:block>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM