获取当前登录的用户

时间:2018-05-31 15:03:29

标签: java hibernate spring-boot spring-security

我正在尝试在Spring启动项目中获取当前登录的用户。我的实体及其关系如下: -

User.java

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

@Id
@Column(unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String email;
private String username;
private String userType;

@OneToOne(mappedBy = "user")
private BankUserDetails bankUserDetails;

@OneToOne(mappedBy ="user")
private SctUserDetails sctUserDetails;

@Column(length = 60)
private String password;

private boolean enabled;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "users_roles", joinColumns =
@JoinColumn(name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "role_id", 
referencedColumnName = "id"))
private Collection<Role> roles;

public User() {
    super();
    this.enabled = true;
}
}

Role.java

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToMany(mappedBy = "roles")
    private Collection<User> users;

    @ManyToMany()
    @JoinTable(name = "roles_privileges", joinColumns =
    @JoinColumn(name = "role_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "privilege_id", 
    referencedColumnName = "id"))
    private Collection<Privilege> privileges;

    private String name;

    public Role() {
        super();
    }

    public Role(final String name) {
        super();
        this.name = name;
    }

    }

Privilege.java

@Entity
public class Privilege {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "privileges")
    private Collection<Role> roles;

    public Privilege() {
        super();
    }

    public Privilege(final String name) {
        super();
        this.name = name;
    }

所以我的控制器(现在)我正在尝试打印当前登录的用户: -

@RequestMapping("/admin")
public String adminPage(Model model){
    System.out.println("logged user "+UserController.getLoggedInUser());
    return "admin";
}

在我的UserController类上我定义了一个静态方法来检索当前登录的用户,如下所示: -

   public static String getLoggedInUser(){
        String username = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if(principal instanceof UserDetails){
            username =  ((UserDetails) principal).getUsername();
        }else {
            username = principal.toString();
        }
        return username;


    }

我的spring安全配置类如下所示: -

@Configuration
@ComponentScan(basePackages = { "com.infodev.pcms.security" })
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Autowired
    private CustomLogoutSuccessHandler myLogoutSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    /*@Autowired
    private CustomWebAuthenticationDetailsSource authenticationDetailsSource;*/

    private BCryptPasswordEncoder passwordEncoder() {
        return SecurityUtils.passwordEncoder();
    }

    @Autowired
    private UserRepository userRepository;

    public SecSecurityConfig() {
        super();
    }

    private static final String[] PUBLIC_MATCHERS = {
            "/css/**",
            "/js/**",
            "/images/**",
            "**/",
            "/newUser",
            "/forgetPassword",
            "/login",
            "/uploads/**",
            "/assets/**",
            "/api/updateCardStatus"
    };

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider());
    }

    @Override
    public void configure(final WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**","/listAllUsers/**");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        // @formatter:off

        http
            .authorizeRequests()

        /*  antMatchers("/**").*/
            .antMatchers(PUBLIC_MATCHERS).
            permitAll().anyRequest().authenticated();
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/login*","/login*", "/logout*", "/signin/**",
            "/signup/**", "/customLogin",
                        "/user/registration*", "/registrationConfirm*",
            "/expiredAccount*", "/registration*",
                        "/badUser*", "/user/resendRegistrationToken*" ,
            "/forgetPassword*", "/user/resetPassword*",
                        "/user/changePassword*", "/emailError*", "/resources/**",
         "/old/user/registration*","/successRegister*","/qrcode*").permitAll()
                .antMatchers("/invalidSession*").anonymous()
                .antMatchers("/user/updatePassword*","/user/savePassword*","/updatePassword*")
         .hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
                .anyRequest().hasAuthority("READ_PRIVILEGE")
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/homepage.html")
                .failureUrl("/login?error=true")
                .successHandler(myAuthenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)

            .permitAll()
                .and()
            .sessionManagement()
                .invalidSessionUrl("/invalidSession.html")
                .maximumSessions(1).sessionRegistry(sessionRegistry()).and()
                .sessionFixation().none()
            .and()
            .logout()
                .logoutSuccessHandler(myLogoutSuccessHandler)
                .invalidateHttpSession(false)

                .deleteCookies("JSESSIONID")
                .permitAll();
    }

    // beans

    @Bean
    public DaoAuthenticationProvider authProvider() {
        final CustomAuthenticationProvider authProvider = 
        new CustomAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

}

MyCustomUserDetails

@Override
public UserDetails loadUserByUsername(final String username)
throws UsernameNotFoundException {
    final String ip = getClientIP();
    if (loginAttemptService.isBlocked(ip)) {
        throw new RuntimeException("blocked");
    }

    try {
        final User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException
       ("No user found with username: " + username);
        }

        org.springframework.security.core.userdetails.User usr= 
       new org.springframework.security.core.userdetails.User
    (user.getUsername(), user.getPassword(), user.isEnabled(),
                true, true, true, getAuthorities(user.getRoles()));
        return usr;
    } catch (final Exception e) {
        throw new RuntimeException(e);
    }
}

// UTIL

private final Collection<? extends GrantedAuthority>
 getAuthorities(final Collection<Role> roles) {
    return getGrantedAuthorities(getPrivileges(roles));
}

private final List<String> getPrivileges(final Collection<Role> roles) {
    final List<String> privileges = new ArrayList<String>();
    final List<Privilege> collection = new ArrayList<Privilege>();
    for (final Role role : roles) {
        collection.addAll(role.getPrivileges());
    }
    for (final Privilege item : collection) {
        privileges.add(item.getName());
    }

    return privileges;
}

private final List<GrantedAuthority> getGrantedAuthorities
(final List<String> privileges) {
    final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    for (final String privilege : privileges) {
        authorities.add(new SimpleGrantedAuthority(privilege));
    }
    return authorities;
}

adminPage方法调用时,会按预期调用getLoggedInUser(),但不会进入if(principal instanceof UserDetails){行。相反,它将执行else子句并返回整个user对象。

enter image description here

我需要在我的控制器上获取当前登录的用户。我该怎么做 ?

1 个答案:

答案 0 :(得分:0)

您应该阅读this。但是你几乎就在那里。

而不是

SecurityContextHolder.getContext().getAuthentication().getPrincipal() 

,你应该使用

SecurityContextHolder.getContext().getAuthentication().getName()

,然后

userDetailsService.loadUserByUsername(name) 

会给你UserDetails。

只需像这样修改你的代码:

@RequestMapping("/admin")
public String adminPage(Principal principal, Model model)

Spring将为您注入主体,检查主体包含的内容,并在必要时执行相同操作(使用登录用户的名称加载UserDetails),如上所述。