java - @AuthenticationPrincipal 抛出异常

标签 java spring authentication spring-security

这个测试项目因为我不知道如何在方法中注入(inject)@AuthenticationPrincipal 注释,我有一些问题,@AuthenticationPrincipal UserDetails 抛出异常

UserDetails userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal()

工作没问题,但我想在方法中注入(inject)此注释,我该怎么做?

当我在方法中添加注解时抛出这个异常

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.security.core.userdetails.UserDetails

如何将 @AuthenticationPrincipal 注入(inject) MainControll 类中的索引方法? 我该如何解决这种情况?

主控类

package com.sencerseven.springsecurityauth.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;



@Controller
public class MainController {

    @RequestMapping(value = {"/"})
    public ModelAndView index(@AuthenticationPrincipal UserDetails userDetails) {
        ModelAndView mv = new ModelAndView("index");

            mv.addObject("user", userDetails);

        return mv;
    }

    @RequestMapping(value = {"/login"})
    public ModelAndView loginPage(@RequestParam(name="error",required = false)String error,
            @RequestParam(name="logout",required = false)String logout) {
        ModelAndView mv = new ModelAndView("login");

        mv.addObject("userClickLoginPage",true);

        return mv;
    }

    @RequestMapping("/perform-logout")
    public String logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if(authentication != null) {
            new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication);
        }

        return "redirect:/";
    }
}

这个类是我的主 Controller


WebSecurityConfig.class

package com.sencerseven.springsecurityauth.security;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public static BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Configuration
    public static class HomeConfigLogin extends WebSecurityConfigurerAdapter {
        @Autowired
        UserDetailsService userDetailsService;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/**").permitAll().and()

                    .formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password")
                    .defaultSuccessUrl("/", true).loginProcessingUrl("/login").and().logout().and().exceptionHandling()
                    .accessDeniedPage("/").and().csrf();
        }

    }
}

我的用户详细信息服务

package com.sencerseven.springsecurityauth.security;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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;

import com.sencerseven.springsecurityauth.dao.UserDAO;
import com.sencerseven.springsecurityauth.dto.Role;

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDAO userDAO;

    @Transactional
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        com.sencerseven.springsecurityauth.dto.User user = userDAO.findByUserName(username);
        List<GrantedAuthority> authorities = buildUserAuthority(user.getRole());

        return buildUserForAuthentication(user, authorities);

    }

    private User buildUserForAuthentication(com.sencerseven.springsecurityauth.dto.User user,
            List<GrantedAuthority> authorities) {
        return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
    }

    private List<GrantedAuthority> buildUserAuthority(Set<Role> userRoles) {

        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();


        for (Role userRole : userRoles) {
            setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
        }

        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

        return Result;
    }

}

用户类

package com.sencerseven.springsecurityauth.dto;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

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

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String username;

    private String password;

    private boolean enabled;

    private String email;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> role;

    public User() {

    }

    public User(String username, String password, boolean enabled, String email, Set<Role> role) {
        this.username = username;
        this.password = password;
        this.enabled = enabled;
        this.email = email;
        this.role = role;
    }

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public boolean isEnabled() {
        return enabled;
    }

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

    public Set<Role> getRole() {
        return role;
    }

    public void setRole(Set<Role> role) {
        this.role = role;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", enabled=" + enabled
                + ", email=" + email + ", role=" + role + "]";
    }

}

角色类

package com.sencerseven.springsecurityauth.dto;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "Role")
public class Role implements Serializable {

    private static final long serialVersionUID = 1L;

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

    private String role;

    @ManyToMany(mappedBy = "role", fetch = FetchType.LAZY)
    private Set<User> user;

    public Role() {
    }

    public Role(String role, Set<User> user) {
        this.role = role;
        this.user = user;
    }

    public int getId() {
        return id;
    }

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

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Set<User> getUser() {
        return user;
    }

    public void setUser(Set<User> user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Role [id=" + id + ", role=" + role + ", user=" + user + "]";
    }

}

最佳答案

如果您使用 WebMvcConfigurationSupport 和 @AuthenticationPrincipal,则必须添加 AuthenticationPrincipalArgumentResolver:

public class WebMvcConfig extends WebMvcConfigurationSupport {

...

@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
   argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
}

关于java - @AuthenticationPrincipal 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50011797/

相关文章:

java - 旋转二维数组中的 block

java - 具有 Activity 事务和连接打开的 LazyInitializationException

asp.net - Visual Studio Development Server (2010) 和 NTLM 授权

Java Crypto Api - 如何选择密码提供者

java - JTable header 中 JButton 上的 ActionListener 卡住应用程序

java - Tomcat容器中c3p0依赖放在哪里

java - Spring MVC Hibernate MySQL - 少1天进入数据库

c# - 具有多个存储库的 ServiceStack 身份验证

java - Servlet 过滤器(自动登录)优先于声明性安全检查

java - Eclipse RCP : How to manage user access permissions to resources?