MehmanBashirov
MehmanBashirov

Reputation: 661

How can I get userInformation in spring security?


Let's imagine I have a rest services in a spring boot application.
For front end I want to login in my application and user must show own informations, such as username, userFullName, birthDay etc.
At first user must get token, then user must get user informations(username, userFullaname, birthDay) with two difference request or When user get token User must get both of them in one operation?

For example as the below code you can see I will return token.

public static void addAuthentication(HttpServletResponse res, Authentication auth) {
    try {
        String concattedRoles = "";
        for (GrantedAuthority ga : auth.getAuthorities()) {
            if (!"".equals(concattedRoles)) {
                concattedRoles += "," + ga.getAuthority();
            } else {
                concattedRoles += ga.getAuthority();
            }

        }

        String JWT = Jwts.builder().setSubject(auth.getName()).claim("roles", concattedRoles)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512, SECRET).compact();
        res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);//add header
        res.getWriter().append("{\"token\":\""+TOKEN_PREFIX + " " + JWT+"\"}");//add body
    }catch (Exception e){
        e.printStackTrace();
    }
}

If the above code I get userinformation from database as the below code, this way is normal way or not?

@Autowired
UserRepository userRepository;
User user = (User)auth.getPrincipal();
String username = user.getUsername();
UserEntity userEntity = userRepository.findByUsername(username);

res.getWriter().append(userEntity);//about such as.

Upvotes: 1

Views: 1301

Answers (3)

MehmanBashirov
MehmanBashirov

Reputation: 661

Thank you to everyone. Finally I solved this problem as the below.
I use UserDetails, UserDetailsService interfaces from org.springframework.security.core.userdetails package.

package com.example.notarydemo.entity;

import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.util.Collection;
import java.util.List;

@Entity

@NamedStoredProcedureQueries({
        @NamedStoredProcedureQuery(name = "search_user",
                procedureName = "search_user",
                resultClasses = {AppUser.class},
                parameters = {
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "id", type = Integer.class),
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "username", type = String.class),
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "enabled", type = String.class),
                        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "cur", type = AppUser.class)
                })})
@Table(name = "APP_USER", schema = "MEHMAN")
public class AppUser {
    private long id;
    private String username;

    private String fulName;
    private String encrytedPassword;
    private long enabled;
    private Collection<UserRole> userRolesById;

    public AppUser(String userName, String fulName) {
        this.username = userName;
        this.fulName = fulName;
    }

    public AppUser() {
    }

    @Id
    @Column(name = "ID", nullable = false, precision = 0)
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Basic
    @Column(name = "USER_NAME", nullable = false, length = 36)
    public String getUsername() {
        return username;
    }

    public void setUsername(String userName) {
        this.username = userName;
    }

    @Basic
    @Column(name = "FULLNAME", nullable = false, length = 45)
    public String getFULLNAME() {
        return fulName;
    }

    public void setFULLNAME(String fullName) {
        this.fulName = fullName;
    }

    @Basic
    @Column(name = "ENCRYTED_PASSWORD", nullable = false, length = 128)
    public String getEncrytedPassword() {
        return encrytedPassword;
    }

    public void setEncrytedPassword(String encrytedPassword) {
        this.encrytedPassword = encrytedPassword;
    }

    @Basic
    @Column(name = "ENABLED", nullable = false, precision = 0)
    public long getEnabled() {
        return enabled;
    }

    public void setEnabled(long enabled) {
        this.enabled = enabled;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AppUser appUser = (AppUser) o;

        if (id != appUser.id) return false;
        if (enabled != appUser.enabled) return false;
        if (username != null ? !username.equals(appUser.username) : appUser.username != null) return false;
        if (encrytedPassword != null ? !encrytedPassword.equals(appUser.encrytedPassword) : appUser.encrytedPassword != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result + (username != null ? username.hashCode() : 0);
        result = 31 * result + (encrytedPassword != null ? encrytedPassword.hashCode() : 0);
        result = 31 * result + (int) (enabled ^ (enabled >>> 32));
        return result;
    }

    @OneToMany(mappedBy = "appUserByUserId")
    @JsonManagedReference
    public Collection<UserRole> getUserRolesById() {
        return userRolesById;
    }

    public void setUserRolesById(Collection<UserRole> userRolesById) {
        this.userRolesById = userRolesById;
    }
}





package com.example.notarydemo.model;

import com.example.notarydemo.entity.AppUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

public class MyUserPrincipal implements UserDetails {
    private AppUser user;

    public MyUserPrincipal(AppUser user) {
        System.out.println(user.getFULLNAME() + user.getUsername() + user.getEnabled());
        this.user = user;
    }

    public AppUser getUser() {
        return user;
    }

    public void setUser(AppUser user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return user.getEncrytedPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        if (user.getEnabled() == 1)
        return true;
        return false;
    }
}





package com.example.notarydemo.config;

import com.example.notarydemo.entity.AppUser;
import com.example.notarydemo.model.MyUserPrincipal;
import com.example.notarydemo.model.UserTokenInfoObject;
import com.example.notarydemo.repository.AppUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private AppUserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            AppUser user = userRepository.findByUsername(username);
            if (user == null)
                throw new UsernameNotFoundException(username);
        return new MyUserPrincipal(user);
    }
}





public static void addAuthentication(HttpServletResponse res, Authentication auth) {
        try {
            String concattedRoles = "";
            for (GrantedAuthority ga : auth.getAuthorities()) {
                if (!"".equals(concattedRoles)) {
                    concattedRoles += "," + ga.getAuthority();
                } else {
                    concattedRoles += ga.getAuthority();
                }

            }

            String JWT = Jwts.builder().setSubject(auth.getName()).claim("roles", concattedRoles)
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET).compact();
            res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
           MyUserPrincipal user = (MyUserPrincipal) auth.getPrincipal();

            System.out.println(user.getUser().getFULLNAME());
            res.getWriter().append("{\"token\":\""+TOKEN_PREFIX + " " + JWT+"\"}");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

http://www.baeldung.com/spring-security-authentication-with-a-database

Upvotes: 0

Steve Perkins
Steve Perkins

Reputation: 177

If you really want to avoid the second request to retrieve user information, you can add the user's birthdate, etc to the claims in the JWT token. Then the token itself contains everything you want to know about the user and you don't need the second trip to the database.

Be aware that this will also increase the size of the token and make encryption and decryption take longer.

Upvotes: 0

Alien
Alien

Reputation: 15878

The "only" things you need to do is create your own UserDetailsService implementation which returns your own implementation of a UserDetails object.

See here for a tutorial which implements a JPA based UserDetailsService.

Answer adapted from https://stackoverflow.com/a/20350591/6572971

Also check other answers too on this thread.

Upvotes: 1

Related Questions