简体   繁体   English

没有为 id null 映射的密码编码器/如何 map 一个 id?

[英]there is no passwordencoder mapped for the id null / how to map an id?

This is my first time using spring, spring security, or doing anything with jwts, so please be patient with me.这是我第一次使用 spring、spring 安全性,或者用 jwts 做任何事情,所以请耐心等待。

If I send a POST request to api/user/login using insomnia with the body如果我使用身体失眠向 api/user/login 发送 POST 请求

{"email": "validmail.com",
"password": "123"}

I get the error 500, Internal Server error, and the exception我收到错误 500、内部服务器错误和异常

ERROR 12736 --- [nio-8088-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]   : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" 

I looked online and i understood it that adding for example {noop} to the front of the password would provide the id with which the password is to be encoded.我在网上看了看,我明白在密码前面添加例如 {noop} 将提供密码编码的 id。

But changing the input to但是将输入更改为

{"email": "validmail.com",
"password": "{noop}123"}

did not change the results.没有改变结果。

Now my question is: How do I provide an id for the DelegatingPasswordEncoder to delegate to?现在我的问题是:我如何为 DelegatingPasswordEncoder 提供一个 id 来委托?

Note that i haven't hashed the passwords entered into my database yet.请注意,我还没有散列输入到我的数据库中的密码。

Relevant code:相关代码:

@Entity
public class User implements UserDetails {

    private static final long serialVersionUID = -9099175240545719086L;
    @Id
    @Column(nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String email;

    @Column
    private String writtenSignaturePath;

    @Column
    private String name;

    @Column
    private String passwordHash;

    @Column(columnDefinition = "BOOLEAN NOT NULL DEFAULT FALSE")
    private boolean isAdmin;

    @Column
    private String twoFACode;

    protected User() {

    }

    public User(final String email) {
        this.email = email;
    }

    @JsonIgnore
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

        if (twoFACode != null){
            String[] roles;
            if (isAdmin){
                roles = new String[]{"user", "admin"};
            } else {
                roles = new String[]{"user"};
            }
            return AuthorityUtils.createAuthorityList(roles);
        }
        return AuthorityUtils.createAuthorityList();
    }

    public Long getId() {
        return id;
    }

    public String getEmail() {
        return email;
    }

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

    public String getWrittenSignaturePath() {
        return writtenSignaturePath;
    }

    public void setWrittenSignaturePath(final String writtenSignaturePath) {
        this.writtenSignaturePath = writtenSignaturePath;
    }


    // This is called getUsername to satisfy the interface. Users are identified by their email, so this should work fine
    @Override
    public String getUsername() {
        return email;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }


    // This is called getPassword to satisfy the interface.
    @Override
    public String getPassword() {
        return passwordHash;
    }

    public String getPasswordHash() {
        return passwordHash;
    }

    public void setPasswordHash(final String passwordHash) {
        this.passwordHash = passwordHash;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public void setAdmin(final boolean admin) {
        isAdmin = admin;
    }

    public String getTwoFACode() {
        return twoFACode;
    }

    public void setTwoFACode(final String twoFACode) {
        this.twoFACode = twoFACode;
    }

    @JsonIgnore
    @Override
    public boolean isAccountNonExpired() { //<6>
        return true;
    }

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

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

    @JsonIgnore
    @Override
    public boolean isEnabled() {
        return true;
    }
}
public interface UserRepository extends CrudRepository<User, String> {
    User findByEmail(String email);
}
public interface UserService extends UserDetailsService {

}
@Service
class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserServiceImpl(final UserRepository userRepository) {
        this.userRepository = userRepository;
    }



    //This is called loadUserByUsername to satisfy the interface. Users are usually identified by their email.
    @Override
    public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
        try {
            return userRepository.findByEmail(email);
        } catch (UsernameNotFoundException e) {
            throw e;
        }
    }

    public UserDetails loadUserByEmail(final String email) throws UsernameNotFoundException {
        try {
            return userRepository.findByEmail(email);
        } catch (UsernameNotFoundException e) {
            throw e;
        }
    }

}
@SpringBootApplication
@EnableJpaRepositories
@EnableTransactionManagement
public class ExampleApplication {

    public static void main(final String... args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}
@ConfigurationProperties("security")
public final class SecurityConstants {

    private String authLoginUrl;

    private String jwtSecret;
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    private final SecurityConstants securityConstants;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, final SecurityConstants securityConstants) {
        this.authenticationManager = authenticationManager;
        this.securityConstants = securityConstants;

        setFilterProcessesUrl(this.securityConstants.getAuthLoginUrl());
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);

        return authenticationManager.authenticate(authenticationToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain filterChain, Authentication authentication) {
        UserDetails user = (UserDetails) authentication.getPrincipal();

        List<String> roles = user.getAuthorities()
            .stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList());

        byte[] signingKey = securityConstants.getJwtSecret().getBytes();

        String token = Jwts.builder()
            .signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
            .setHeaderParam("typ", securityConstants.getTokenType())
            .setIssuer(securityConstants.getTokenIssuer())
            .setAudience(securityConstants.getTokenAudience())
            .setSubject(user.getUsername())
            .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // + 1 Tag
            .claim("rol", roles)
            .compact();

        response.addHeader(securityConstants.getTokenHeader(), securityConstants.getTokenPrefix() + token);
    }
}

    // JWT Token-Standardvalues
    private String tokenHeader;
    private String tokenPrefix;
    private String tokenType;
    private String tokenIssuer;
    private String tokenAudience;

    public String getAuthLoginUrl() {
        return authLoginUrl;
    }

    public void setAuthLoginUrl(String authLoginUrl) {
        this.authLoginUrl = authLoginUrl;
    }

    public String getJwtSecret() {
        return jwtSecret;
    }

    public void setJwtSecret(String jwtSecret) {
        this.jwtSecret = jwtSecret;
    }

    public String getTokenHeader() {
        return tokenHeader;
    }

    public void setTokenHeader(String tokenHeader) {
        this.tokenHeader = tokenHeader;
    }

    public String getTokenPrefix() {
        return tokenPrefix;
    }

    public void setTokenPrefix(String tokenPrefix) {
        this.tokenPrefix = tokenPrefix;
    }

    public String getTokenType() {
        return tokenType;
    }

    public void setTokenType(String tokenType) {
        this.tokenType = tokenType;
    }

    public String getTokenIssuer() {
        return tokenIssuer;
    }

    public void setTokenIssuer(String tokenIssuer) {
        this.tokenIssuer = tokenIssuer;
    }

    public String getTokenAudience() {
        return tokenAudience;
    }

    public void setTokenAudience(String tokenAudience) {
        this.tokenAudience = tokenAudience;
    }
}
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig
    extends GlobalMethodSecurityConfiguration {
}
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

    private static final Logger LOG = LoggerFactory.getLogger(JwtAuthorizationFilter.class);
    private final  SecurityConstants securityConstants;

    public JwtAuthorizationFilter(AuthenticationManager authenticationManager, final SecurityConstants securityConstants) {
        super(authenticationManager);
        this.securityConstants = securityConstants;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws IOException, ServletException {
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
        if (authentication == null) {
            filterChain.doFilter(request, response);
            return;
        }

        SecurityContextHolder.getContext().setAuthentication(authentication);
        filterChain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = request.getHeader(securityConstants.getTokenHeader());
        if (token != null && !token.equals("") && token.startsWith(securityConstants.getTokenPrefix())) {
            try {
                byte[] signingKey = securityConstants.getJwtSecret().getBytes();

                Jws<Claims> parsedToken = Jwts.parserBuilder()
                    .setSigningKey(signingKey).build()
                    .parseClaimsJws(token.replace(securityConstants.getTokenPrefix(), "").strip());

                String username = parsedToken.getBody().getSubject();

                List<SimpleGrantedAuthority> authorities = ((List<?>) parsedToken.getBody()
                    .get("rol")).stream()
                    .map(authority -> new SimpleGrantedAuthority((String) authority))
                    .collect(Collectors.toList());

                if (username != null && !username.equals("")) {
                    return new UsernamePasswordAuthenticationToken(username, null, authorities);
                }
            } catch (ExpiredJwtException exception) {
                LOG.warn("Request to parse expired JWT : {} failed : {}", token, exception.getMessage());
            } catch (UnsupportedJwtException exception) {
                LOG.warn("Request to parse unsupported JWT : {} failed : {}", token, exception.getMessage());
            } catch (MalformedJwtException exception) {
                LOG.warn("Request to parse invalid JWT : {} failed : {}", token, exception.getMessage());
            } catch (SignatureException exception) {
                LOG.warn("Request to parse JWT with invalid signature : {} failed : {}", token, exception.getMessage());
            } catch (IllegalArgumentException exception) {
                LOG.warn("Request to parse empty or null JWT : {} failed : {}", token, exception.getMessage());
            }
        }

        return null;
    }
}
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    private final SecurityConstants securityConstants;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, final SecurityConstants securityConstants) {
        this.authenticationManager = authenticationManager;
        this.securityConstants = securityConstants;

        setFilterProcessesUrl(this.securityConstants.getAuthLoginUrl());
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        String line;
        StringBuilder builder = new StringBuilder();
        //Why doesn't this get closed? Idk, have to take care of this later
        try {
            BufferedReader reader = request.getReader();
            while ((line=reader.readLine()) != null){
                builder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        String body = builder.toString();
        String[] params = body.split(",");
        String email = params[0].substring(12, params[0].length()-1);
        String password = params[1].substring(14, params[1].length()-2);
        System.out.println(email);
        System.out.println(password);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);

        return authenticationManager.authenticate(authenticationToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain filterChain, Authentication authentication) {
        UserDetails user = (UserDetails) authentication.getPrincipal();

        List<String> roles = user.getAuthorities()
            .stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList());

        byte[] signingKey = securityConstants.getJwtSecret().getBytes();

        String token = Jwts.builder()
            .signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
            .setHeaderParam("typ", securityConstants.getTokenType())
            .setIssuer(securityConstants.getTokenIssuer())
            .setAudience(securityConstants.getTokenAudience())
            .setSubject(user.getUsername())
            .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // + 1 Tag
            .claim("rol", roles)
            .compact();

        response.addHeader(securityConstants.getTokenHeader(), securityConstants.getTokenPrefix() + token);
    }
}
@Configuration
@EnableWebSecurity
@EnableAutoConfiguration
@EnableConfigurationProperties(SecurityConstants.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final SecurityConstants securityConstants;

    @Autowired
    public SecurityConfig(SecurityConstants securityConstants) {
        this.securityConstants = securityConstants;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").permitAll()
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager(), securityConstants))
            .addFilter(new JwtAuthorizationFilter(authenticationManager(), securityConstants))
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Autowired
    public void configureGlobal(final UserDetailsService userDetailsService,
                                final PasswordEncoder passwordEncoder,
                                final AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
        corsConfiguration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "PATCH", "DELETE"));
        source.registerCorsConfiguration("/**", corsConfiguration);

        return source;
    }
}

Spring Security requires a PasswordEncoder when working with user passwords, you have not provided information about it. Spring Security 在使用用户密码时需要PasswordEncoder ,您尚未提供相关信息。 You need declare bean with it, for example using BCryptPasswordEncoder :您需要用它声明 bean,例如使用BCryptPasswordEncoder

@Bean
PasswordEncoder getPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

and use it in your code.并在您的代码中使用它。 You can find many examples on the internet, like this .你可以在互联网上找到很多例子,像这样

If, for any reason, we don't want to encode the configured password, we can make use of the NoOpPasswordEncoder .如果出于任何原因,我们不想对配置的密码进行编码,我们可以使用NoOpPasswordEncoder

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过数据库身份验证,没有映射ID为“ null”的PasswordEncoder - There is no PasswordEncoder mapped for the id “null” with database authentication Spring Security 中没有为 id “null”映射 PasswordEncoder - There is no PasswordEncoder mapped for the id “null” in Spring Security Spring 安全性 5:没有为 id“null”映射 PasswordEncoder - Spring Security 5 : There is no PasswordEncoder mapped for the id "null" Spring 安全性与 jdbcAuthentication throws 没有为 id “null”映射 PasswordEncoder - Spring Security with jdbcAuthentication throws There is no PasswordEncoder mapped for the id “null” Oauth2客户端凭证流+ Spring Boot2引发对于id“ null”错误,没有映射PasswordPasscoder&gt; - Oauth2 Client Credentials Flow + Spring Boot2 throwing There is no PasswordEncoder mapped > for the for the id “null” error 基于Spring Security XML的配置:java.lang.IllegalArgumentException:没有为id“null”映射的PasswordEncoder - Spring Security XML based configuration : java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" 如何从映射的超类继承@Id? - How to inherit @Id from mapped superclass? 为映射项生成 ID - Generate ID for mapped item 如何在聚合中映射_id参数 - How to map _id parameter in aggregation jpa映射的超类没有id - jpa mapped superclass without id
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM