【问题标题】:Spring security 401 unauthorized. Looks like problem with filter or permitAll()Spring Security 401 未经授权。看起来像 filter 或 permitAll() 的问题
【发布时间】:2020-03-29 02:04:58
【问题描述】:

//我第一个回答中的问题解决方案。

我编写了一个简单的 Spring Security 项目,并且似乎是正确的,因为我以前做过,并且几乎使用相同的代码一切都很好,但是现在我不能允许“/auth/login”的请求。

有趣的是,在配置类 http.antMatchers('/auth/**").permitAll 中,但我只能通过路径 /auth/reg./auth/login 访问 - 返回 401。

也许有人熟悉这个问题,会很乐意帮助我解决这个问题。

我的安全配置类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled = true
)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private UserDetailsServiceImpl userDetailsService;
    private JwtEntryPoint entryPoint;

    @Autowired
    public WebSecurityConfig(UserDetailsServiceImpl userDetailsService,
                             JwtEntryPoint entryPoint) {
        this.userDetailsService = userDetailsService;
        this.entryPoint = entryPoint;
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authorizeRequests()
                .antMatchers("/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(entryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public JwtTokenFilter jwtTokenFilter() {
        return new JwtTokenFilter();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

休息控制器:

@RestController
@RequestMapping("/auth")
public class AuthController {

    private AuthenticationManager authManager;
    private UserRepository userRepository;
    private RoleRepository roleRepository;
    private PasswordEncoder encoder;
    private JwtTokenProvider tokenProvider;

    @Autowired
    public AuthController(AuthenticationManager authManager,
                          UserRepository userRepository,
                          RoleRepository roleRepository,
                          PasswordEncoder encoder,
                          JwtTokenProvider provider) {
        this.authManager = authManager;
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.encoder = encoder;
        this.tokenProvider = provider;
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginForm loginForm) {
        Authentication authentication = authManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginForm.getUsername(), loginForm.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);

        String token = tokenProvider.generateJwtToken(authentication);
        UserDetails userPrincipal = (UserDetails) authentication.getPrincipal();
        return ResponseEntity.ok(new JwtResponse(token, userPrincipal.getUsername(), userPrincipal.getAuthorities()));
    }

    @PostMapping("/reg")
    public ResponseEntity<?> register(@ModelAttribute RegForm regForm) {
        if (userRepository.existsUserByUsername(regForm.getUsername()))
            return ResponseEntity.badRequest().body("This username is already taken! Choose another one!");
        User user = new User(regForm.getUsername(),
                encoder.encode(regForm.getPassword()),
                UploadFileUtil.getStoragePath(regForm.getFile().getOriginalFilename()));
        Set<Role> defaultRoles = new HashSet<>();
        defaultRoles.add(roleRepository.findRoleByUserRole(Roles.USER));
        user.setUserRoles(defaultRoles);
        userRepository.save(user);
        return ResponseEntity.ok().body("User registered successfully!");
    }
}

感谢任何帮助。

【问题讨论】:

    标签: java spring-boot spring-security jwt-auth


    【解决方案1】:

    原因不在安全配置中,而是在 UserPrincipal 类中实现了 UserDetails。当您实现包括 getter 在内的所有方法时,它们默认返回 false 和 null。因此,当我尝试从主体获取字段时,它们将 null 返回到身份验证中,因此密码不一样,我得到了未经授权的响应 401。

    所以不要忘记以正确的方式重写方法,这样你就不会因为奇怪的错误而浪费时间。

    感谢所有提供帮助的人,没有人。

    public class UserPrincipal implements UserDetails {
    
        private long id;
        private String username;
        @JsonIgnore
        private String password;
        private Collection<? extends GrantedAuthority> authorities;
    
        public static UserPrincipal build(User user) {
            List<GrantedAuthority> authorities = user.getUserRoles().stream().map(role ->
                new SimpleGrantedAuthority(role.getUserRole().name())
            ).collect(Collectors.toList());
            return new UserPrincipal(
                        user.getId(),
                        user.getUsername(),
                        user.getPassword(),
                        authorities
            );    }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }
    
        @Override
        public String getPassword() {
            return this.password;
        }
    
        @Override
        public String getUsername() {
            return this.username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    

    【讨论】:

      猜你喜欢
      • 2021-02-02
      • 2023-01-11
      • 1970-01-01
      • 2017-05-26
      • 2022-01-21
      • 1970-01-01
      • 2019-08-09
      • 2017-10-26
      • 2016-12-14
      相关资源
      最近更新 更多