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

11

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

Figurative answered 29/1, 2016 at 17:19 Comment(5)
How about adding the user details in a Cookie which will be accessible to every webpage within the domain?Opportina
use spring security taglib... considering you are using thymeleaf as template refer this : thymeleaf.org/doc/articles/springsecurity.htmlLayla
@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.Figurative
@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? ThanksFigurative
SO already has an answer - #7808467Layla
F
26

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>
Figurative answered 29/1, 2016 at 19:0 Comment(0)
S
17

When using Spring Security 4 and Thymeleaf 3:

<span th:text="${#authentication.getPrincipal().getUsername()}"></span>
Selfhood answered 11/7, 2017 at 6:46 Comment(1)
explain more about your answerSutlej
T
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>
Thaw answered 12/12, 2019 at 2:28 Comment(0)
V
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

Verism answered 28/3, 2018 at 12:6 Comment(2)
do you know of a way to do so with the user's role? like <span sec:authentication="role">Bob</span>Floss
Sure. Just use this: <span sec:authentication="principal.authorities">[ROLE_USER, ROLE_ADMIN]</span> that should do the trick. Here are some hints to find: spring security thymeleaf. I hope this helps.Verism
B
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().

Bourbonism answered 24/9, 2018 at 10:46 Comment(0)
B
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

Balladmonger answered 8/2, 2019 at 9:45 Comment(0)
L
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

Limitation answered 8/11, 2018 at 16:46 Comment(0)
A
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">

Avens answered 11/4, 2020 at 16:23 Comment(0)
I
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>
Indonesian answered 17/1, 2023 at 8:57 Comment(0)
G
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

Gudrunguelderrose answered 31/3, 2023 at 5:22 Comment(0)
L
0

I've this configuration with Thymeleaf 3.1.2, Sprig Boot 3.1.3 and Spring Security 6.0.11 (Java 17):

Spring Boot:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

Thymeleaf for Spring Security:

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

HTML Namespace:

xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

HTML Authenticated user, option 1:

<span sec:authentication="principal.firstName"></span>

HTML Authenticated user, option 2:

<p th:text="${#authentication.principal.fisrtName}"></p>

Object UserLogin:

public class UsuarioLogin implements Serializable {

   private static final long serialVersionUID = 1L;

   private Integer cve;
   private String name;
   private String firstName;
   private Perfil perfil;

Ref: https://www.baeldung.com/get-user-in-spring-security

Labio answered 18/10, 2023 at 3:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.