当前位置: 首页 > 知识库问答 >
问题:

Spring安全用户不能投向类用户

宫修贤
2023-03-14

首先,请记住我是一个Java新手,这对我来说都是未探索的领域。

我遵循了一个指南(大约6个月前)来实现Spring Security性,但从未找到一个专门用于单独前端层的指南。

在实现令牌之前,每个步骤都有效,我得到了这个错误:

class org.springframework.security.core.userdetails.User cannot be cast to class com.example.springboot.model.User

我在这里看到过其他类似的帖子,尽管它们讨论的内容不同

例如。

>

  • 用户不能被强制转换为com.example.security.CustomUserDetailsSpring Security-这将讨论不返回实体

    Spring security Userdetails无法转换为我自己的用户实现-讨论了JwtAuthenticationFilter类中的错误导入语句< code > org . spring framework . security . core . user details . user

    首先,我使用org.springframework.security.core.userdetails.userDetails(类似于指南作者)

    其次,我有三个例子来描述这个提供者(2<code>userDetails</code>和1<code>userDetailsService</code>)

    1x 用户JWT身份验证过滤器中的详细信息

    1x 用户详细信息JWT身份验证中的服务过滤器

    < code>JWTTokenHelper中的1x userDetails

    这是endpoint:

        @PostMapping("/auth/login")
        public ResponseEntity<?> login(@RequestBody AuthenticationRequest authenticationRequest) throws InvalidKeySpecException, NoSuchAlgorithmException {
    
            final Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                    authenticationRequest.getUserName(), authenticationRequest.getPassword()));
    
            SecurityContextHolder.getContext().setAuthentication(authentication);
    
            User user=(User)authentication.getPrincipal(); // crashes here
            String jwtToken=jWTTokenHelper.generateToken(user.getUsername());
    
            LoginResponse response=new LoginResponse();
            response.setToken(jwtToken);
    
            return ResponseEntity.ok(response);
        }
    

    它在注释行返回一个错误,进一步钻取并查看以下类,它会到达第一个if语句(我认为是如果它不为空?)

    然后转到filterChain.doFilter并崩溃

    JWTAuthenticationFilter 如下所示:

    package com.example.springboot.config;
    import java.io.IOException;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.web.authentication.WebAuthenticationDetails;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    public class JWTAuthenticationFilter extends OncePerRequestFilter {
    
        private UserDetailsService userDetailsService;
        private JWTTokenHelper jwtTokenHelper;
    
        public JWTAuthenticationFilter(UserDetailsService userDetailsService, JWTTokenHelper jwtTokenHelper) {
            this.userDetailsService = userDetailsService;
            this.jwtTokenHelper = jwtTokenHelper;
    
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
            String authToken = jwtTokenHelper.getToken(request);
            if (null != authToken) { // fails this check
                String userName = jwtTokenHelper.getUsernameFromToken(authToken);
                if (null != userName) {
                    UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
                    if (jwtTokenHelper.validateToken(authToken, userDetails)) {
                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                        authentication.setDetails(new WebAuthenticationDetails(request));
    
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                }
            }
            filterChain.doFilter(request, response); // returns error here
        }
    }
    

    JWTTokenHelper,如下所示:

    package com.example.springboot.config;
    
    import java.security.NoSuchAlgorithmException;
    import java.security.spec.InvalidKeySpecException;
    import java.util.Date;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
    
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    @Component
    public class JWTTokenHelper {
    
        @Value("${jwt.auth.app}")
        private String appName;
    
        @Value("${jwt.auth.secret_key}")
        private String secretKey;
    
        @Value("${jwt.auth.expires_in}")
        private int expiresIn;
    
        private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;
    
        public JWTTokenHelper(String appName, String secretKey, int expiresIn, SignatureAlgorithm SIGNATURE_ALGORITHM) {
            this.appName = appName;
            this.secretKey = secretKey;
            this.expiresIn = expiresIn;
            this.SIGNATURE_ALGORITHM = SIGNATURE_ALGORITHM;
        }
    
        public JWTTokenHelper() { }
    
        private Claims getAllClaimsFromToken(String token) {
            Claims claims;
            try {
                claims = Jwts.parser()
                        .setSigningKey(secretKey)
                        .parseClaimsJws(token)
                        .getBody();
            } catch (Exception e) {
                claims = null;
            }
            return claims;
        }
    
        public String getUsernameFromToken(String token) {
            String username;
            try {
                final Claims claims = this.getAllClaimsFromToken(token);
                username = claims.getSubject();
            } catch (Exception e) {
                username = null;
            }
            return username;
        }
    
        public String generateToken(String username) throws InvalidKeySpecException, NoSuchAlgorithmException {
            return Jwts.builder()
                    .setIssuer( appName )
                    .setSubject(username)
                    .setIssuedAt(new Date())
                    .setExpiration(generateExpirationDate())
                    .signWith( SIGNATURE_ALGORITHM, secretKey )
                    .compact();
        }
    
        private Date generateExpirationDate() {
            return new Date(new Date().getTime() + expiresIn * 1000);
        }
    
        public Boolean validateToken(String token, UserDetails userDetails) {
            final String username = getUsernameFromToken(token);
            return (
                    username != null &&
                            username.equals(userDetails.getUsername()) &&
                            !isTokenExpired(token)
            );
        }
    
        public boolean isTokenExpired(String token) {
            Date expireDate=getExpirationDate(token);
            return expireDate.before(new Date());
        }
    
    
        private Date getExpirationDate(String token) {
            Date expireDate;
            try {
                final Claims claims = this.getAllClaimsFromToken(token);
                expireDate = claims.getExpiration();
            } catch (Exception e) {
                expireDate = null;
            }
            return expireDate;
        }
    
    
        public Date getIssuedAtDateFromToken(String token) {
            Date issueAt;
            try {
                final Claims claims = this.getAllClaimsFromToken(token);
                issueAt = claims.getIssuedAt();
            } catch (Exception e) {
                issueAt = null;
            }
            return issueAt;
        }
    
        public String getToken( HttpServletRequest request ) {
            String authHeader = getAuthHeaderFromHeader( request );
            if ( authHeader != null && authHeader.startsWith("Bearer ")) {
                return authHeader.substring(7);
            }
    
            return null;
        }
    
        public String getAuthHeaderFromHeader( HttpServletRequest request ) {
            return request.getHeader("Authorization");
        }
    }
    

    对于一个被描述为“简单实现”的东西来说,这个实现相当长(14个类),我不知道哪个部分导致了错误。任何建议都非常感谢!:)

    编辑:

    EDIT2:自定义用户详细信息服务类:

    package com.example.springboot.service;
    
    import com.example.springboot.model.User;
    import com.example.springboot.repository.UserDetailsRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    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 CustomUserService implements UserDetailsService {
    
        @Autowired
        UserDetailsRepository userDetailsRepository;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userDetailsRepository.findByUserName(username);
            if (user != null){ return user; }
            else{ throw new UsernameNotFoundException("Incorrect username:" + username); }
        }
    }
    
    
  • 共有1个答案

    柳涵映
    2023-03-14

    正如@Marcus Hert da Corego所建议的

    org . spring framework . security . core . user details . user,这是您在UserDetailsService中返回的实现。但是,在您的控制器中,您试图将Spring Security的实现强制转换到您的com . example . Spring boot . model . user

    import org.springframework.security.core.userdetails.User;
    

    尽管该指南遇到了其他问题

     类似资料:
    • 我正在用Hibernate和SpringSecurity在SpringMVC4中做一个项目。在这个项目中,我有三个角色:<code>ROLE_USER 用户将像常规注册网站一样注册,但我对如何通过注册过程在数据库中保存新用户,如何保存Spring Security定义的新用户和数据库以及如何使用Hibernate获取该信息感到困惑。 谢谢。

    • 我想找到一种方法,使悬停属性在投票后保持活动状态,这是状态,并让Javascript或Firebase记住为该用户保持投票图标处于该状态。所以当一个用户投了几个名字,然后再回到页面时,他们会看到他们投了哪些名字,他们投的是什么。 我正在寻找如何实现这一目标的想法。 目前,在firebase中,我将用户的身份验证ID(uid)保存在他们投票的每个人的名字中,或者是1或者是-1表示支持或支持。我确信可

    • 因此,作为一个初学者,我曾尝试使用spring boot 2.2.11、spring security、thymeleaf和json web令牌创建一个ecommmerce网站,我的问题是,当用户对模板进行身份验证时,即使我在模板中放置了thymeleaf的isAnonyms和IsAuthentificated标记,模板也没有更改。 我有两个问题: 1-/如何告诉所有控制器用户已经登录? 2-/如

    • 这是关于V.4(MVC+安全性)的。我实现了,其中在方法中向用户授予其权限。让我们简单地说: 还有一个安全控制器,其中有一个带有注释的带注释的方法: 正如您在方法中看到的,我显式地将角色授予了用户。但是,当我尝试访问时,我得到一个异常: 2016-04-19 10:25:16,899 DEBUG(http-nio-8080-exec-9)[org.springframework.security.

    • 问题内容: 在我的网站上,我有一个名为的变量,其中包含来自表单的输入。然后,我在用户页面上显示此变量(通过echo)。 使用此变量来避免任何安全风险的最佳方法是什么?我使用,但这还不够。 此变量也将保存到MySQL数据库。 问题答案: 为避免严重的安全问题,必须执行两项非常重要的操作。 您需要先对用户输入进行转义,然后再将其放入SQL查询中。转义表示转义所有特殊字符,如; 幸运的是,有一个函数已经

    • securityconfig.java