17

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, e.g. some-logged-in-page.html in this example? Thanks

Dee
  • 573
  • 1
  • 4
  • 10
  • How about adding the user details in a Cookie which will be accessible to every webpage within the domain? – Aaditya Gavandalkar Jan 29 '16 at 17:28
  • 1
    use spring security taglib... considering you are using thymeleaf as template refer this : http://www.thymeleaf.org/doc/articles/springsecurity.html – Balaji Krishnan Jan 29 '16 at 17:29
  • @AadityaGavandalkar. Thanks for the suggestion. I suppose I could somehow set the data in a cookie and read it via JavaScript, but I believe there ought to be a decent way to access the same data server-side. In PHP for example we could set the data in $_SESSION and access it in any view potentially. – Dee Jan 29 '16 at 18:00
  • @BalajiKrishnan. Thanks as well. I tried using the sec:authentication tag, but I couldn't figure out a way to fetch the information I need. Perhaps you could write an answer showing how you can get custom information like firstName in my example? Thanks – Dee Jan 29 '16 at 18:05
  • SO already has an answer - http://stackoverflow.com/questions/7807967/accessing-my-custom-user-object-in-jsp-page-using-spring-3-security – Balaji Krishnan Jan 29 '16 at 18:09

10 Answers10

25

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>
Dee
  • 573
  • 1
  • 4
  • 10
16

When using Spring Security 4 and Thymeleaf 3:

<span th:text="${#authentication.getPrincipal().getUsername()}"></span>
B378
  • 987
  • 2
  • 12
  • 27
9

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>
Nayan
  • 1,521
  • 2
  • 13
  • 27
user1677230
  • 1,024
  • 9
  • 3
4

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

Thomas Lang
  • 1,285
  • 17
  • 35
  • do you know of a way to do so with the user's role? like `Bob` – Scaramouche Oct 08 '18 at 22:48
  • Sure. Just use this: `[ROLE_USER, ROLE_ADMIN]` that should do the trick. Here are some hints to find: [spring security thymeleaf](https://www.baeldung.com/spring-security-thymeleaf). I hope this helps. – Thomas Lang Oct 10 '18 at 06:14
1

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().

Tanaji Kolekar
  • 97
  • 1
  • 11
1

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

0

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

LINK

sunitkatkar
  • 1,958
  • 1
  • 14
  • 12
0

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">

Ullas Hunka
  • 2,119
  • 1
  • 15
  • 28
0

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>
mkkabi
  • 611
  • 8
  • 11
0

On 2023-March, to display username from either local or social login(like Facebook), I took this method: (when I'm using)

  • spring boot version: 3.0.4
  • related tech: Maven and Lombok

pom.xml

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

html top

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org"
    xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

html body

<h3 th:inline="text">
    user: <span sec:authentication="name">not found</span>
</h3>

bean class

@AllArgsConstructor
public class CustomOAuth2User implements OAuth2User {

    private OAuth2User oAuth2User;

    @Override
    public String getName() {
        return oAuth2User.getAttribute("name");
    }
}

Part of rendered view page: enter image description here

Park JongBum
  • 1,245
  • 1
  • 16
  • 27