如何指定应使用哪种Authentication Provider? 我正在建立电子商务系统。有一个用于制作订单(例如“存储”)的管理面板,在Spring Boot中的服务器应用程序。要分开逻辑,我有多桌子athenti ...

问题描述 投票:0回答:1
@Entity @Table(name = "customers") public class Customer extends User { @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "profile_id") private Profile profile; public Customer() {} public Profile getProfile() { return profile; } public void setProfile(Profile profile) { this.profile = profile; } }

雇员

admin面板auth:
@Entity
@Table(name = "employees")
public class Employee extends User {
    @NotNull
    private EmployeeRole role;

    public Employee() {
        // new employee has the EMPLOYEE role by default
        role = EmployeeRole.EMPLOYEE;
    }

    public EmployeeRole getRole() {
        return role;
    }

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

    @Override
    @Transient
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority(role.name()));
    }
}

雇员可以具有

admin
雇员的角色。在这种情况下没关系。 Customer

没有任何角色。 用户实现userdetails. 我的配置是: @Configuration @EnableWebSecurity public class SecurityConfiguration { private final EmployeeService employeeService; private final CustomerService customerService; private final CorsConfigurationSource dashboardCorsConfigurationSource; private final CorsConfigurationSource corsConfigurationSource; public SecurityConfiguration(EmployeeService employeeService, CustomerService customerService, @Qualifier("dashboard-cors-configuration-source") CorsConfigurationSource dashboardCorsConfigurationSource, @Qualifier("cors-configuration-source") CorsConfigurationSource corsConfigurationSource) { this.employeeService = employeeService; this.customerService = customerService; this.dashboardCorsConfigurationSource = dashboardCorsConfigurationSource; this.corsConfigurationSource = corsConfigurationSource; } @Bean @Order(0) public SecurityFilterChain employeeSecurityFilterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity.securityMatcher("/api/employee/**") .csrf(AbstractHttpConfigurer::disable) .cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configurationSource(dashboardCorsConfigurationSource) ) .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers("/api/employee/auth/login") .permitAll() .anyRequest() .authenticated() ) .sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer -> httpSecurityOAuth2ResourceServerConfigurer.jwt(Customizer.withDefaults()) ) .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()) .accessDeniedHandler(new BearerTokenAccessDeniedHandler()) ) //.userDetailsService(employeeService) .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) ) .build(); } @Bean @Order(2) public SecurityFilterChain customerSecurityFilterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity.securityMatcher("/api/customer/**") .csrf(AbstractHttpConfigurer::disable) .cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configurationSource(corsConfigurationSource)) .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry.requestMatchers( "/api/customer/register", "/api/customer/auth/login" ) .permitAll() .anyRequest() .authenticated() ) .sessionManagement(httpSecuritySessionManagementConfigurer -> httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer -> httpSecurityOAuth2ResourceServerConfigurer.jwt(Customizer.withDefaults()) ) .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> httpSecurityExceptionHandlingConfigurer .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()) .accessDeniedHandler(new BearerTokenAccessDeniedHandler()) ) //.userDetailsService(customerService) .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) ) .build(); } } @Configuration public class AuthenticationManagerConfiguration { private final EmployeeService employeeService; private final CustomerService customerService; private final PasswordEncoder passwordEncoder; public AuthenticationManagerConfiguration(EmployeeService employeeService, CustomerService customerService, PasswordEncoder passwordEncoder) { this.employeeService = employeeService; this.customerService = customerService; this.passwordEncoder = passwordEncoder; } @Bean public AuthenticationManager authenticationManager() { DaoAuthenticationProvider employeeDaoAuthenticationProvider = new DaoAuthenticationProvider(); employeeDaoAuthenticationProvider.setUserDetailsService(employeeService); employeeDaoAuthenticationProvider.setPasswordEncoder(passwordEncoder); DaoAuthenticationProvider customerDaoAuthenticationProvider = new DaoAuthenticationProvider(); customerDaoAuthenticationProvider.setUserDetailsService(customerService); customerDaoAuthenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(employeeDaoAuthenticationProvider, customerDaoAuthenticationProvider); } } @Service public class AuthenticationService { private final JwtEncoder jwtEncoder; public AuthenticationService(JwtEncoder jwtEncoder) { this.jwtEncoder = jwtEncoder; } public String getToken(Authentication authentication) { User user = (User) authentication.getPrincipal(); List<String> roles = user.getAuthorities() .stream() .map(GrantedAuthority::getAuthority) .toList(); Instant now = Instant.now(); JwtClaimsSet claimsSet = JwtClaimsSet.builder() .issuer("e-commerce") .issuedAt(now) .expiresAt(now.plus(1, ChronoUnit.DAYS)) .subject(authentication.getName()) .claim("scope", roles) .build(); return jwtEncoder.encode(JwtEncoderParameters.from(claimsSet)) .getTokenValue(); } } login端点正常工作,我得到令牌,但是解码时存在问题:

this this是

{ "iss": "e-commerce", "sub": "[email protected]", "exp": 1740480478, "iat": 1740394078, "scope": [ "ADMIN" ] }
所有的东西都很好,并且有
customer
代币:
{
  "iss": "e-commerce",
  "sub": "[email protected]",
  "exp": 1740480575,
  "iat": 1740394175,
  "scope": [
    "ADMIN" // why it is here?? It should be an empty array.
  ]
}

有问题。 Spring Boot使用错误的

AuthenticationProvider

,并用错误的表格对我进行身份验证。我在这两个表中都有相同的电子邮件地址,因为我将逻辑分开,因此这些用户“不同”的用户除了具有相同的电子邮件之外。生活场景 - 您正在商店工作,因此您可以访问管理面板,但也可以私下下达订单。这就是为什么相同的电子邮件都有这种情况。 我也会得到警告Found 2 UserDetailsService beans, with names [customerService, employeeService]. Global Authentication Manager will not use a UserDetailsService for username/password login. Consider publishing a single UserDetailsService bean.

i不能制作单个

用户删除sservice并过滤两个表,因为这两个实体通过逻辑不同。我需要以某种方式指定正确的authenticationprovider可能。

我不想制作两个单独的服务器应用程序,因为刚刚复制和粘贴的代码将有很多相同的代码。这就是为什么我做多桌验证。
	

应该对其进行审查

根据我收到的评论和春季文档,我可能找到了一个解决方案。 首先,我基于路径创建了一个:

AuthenticationManagerResolver<HttpServletRequest>

我不必在我的

@Configuration public class AuthenticationManagerConfiguration { private final EmployeeService employeeService; private final CustomerService customerService; private final PasswordEncoder passwordEncoder; public AuthenticationManagerConfiguration(EmployeeService employeeService, CustomerService customerService, PasswordEncoder passwordEncoder) { this.employeeService = employeeService; this.customerService = customerService; this.passwordEncoder = passwordEncoder; } private AuthenticationManager dashboardAuthenticationManager() { DaoAuthenticationProvider employeeDaoAuthenticationProvider = new DaoAuthenticationProvider(); employeeDaoAuthenticationProvider.setUserDetailsService(employeeService); employeeDaoAuthenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(employeeDaoAuthenticationProvider); } private AuthenticationManager appAuthenticationManager() { DaoAuthenticationProvider customerDaoAuthenticationProvider = new DaoAuthenticationProvider(); customerDaoAuthenticationProvider.setUserDetailsService(customerService); customerDaoAuthenticationProvider.setPasswordEncoder(passwordEncoder); return new ProviderManager(customerDaoAuthenticationProvider); } @Bean public AuthenticationManagerResolver<HttpServletRequest> pathAuthenticationManagerResolver() { return (httpServletRequest) -> { if (httpServletRequest.getRequestURI().startsWith("/api/app/")) { return appAuthenticationManager(); } else if (httpServletRequest.getRequestURI().startsWith("/api/dashboard/")) { return dashboardAuthenticationManager(); } throw new OAuth2AuthenticationException("Invalid request"); }; } } 中添加.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(pathAuthenticationManagerResolver()));。除了我更改的URL之外,它与问题相同。没关系 当我添加时,我一直收到

SecurityFilterChain

。可能是因为我根本忽略了JWT,或者也许我必须在这种情况下添加一些过滤器。

我需要更改的最后一件事是在我的控制器中to
spring spring-boot spring-security
1个回答
0
投票

AuthenticationManager

对我有用。让我知道是否有更好的解决方案。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.