gpt4 book ai didi

java - 使用 Spring Security OAuth2 验证不同的用户类型

转载 作者:行者123 更新时间:2023-12-02 01:55:33 25 4
gpt4 key购买 nike

我想使用两种类型的用户:普通用户和管理员。现在我已经有了一个基础设施,其中管理员和用户是两种完全不同的类型:用户有许多仅与他们相关的东西( Controller 、表、服务等),对于管理员来说也是如此。因此,它们是数据库中不同的实体和不同的表,我不想将它们组合起来,因为它们是不同的。但现在只有用户可以使用 Spring Security OAuth2 登录,但管理员不能登录,因此他们无法登录。请注意,我使用自己的授权和资源服务器。

所以,我想允许 Spring Security 对用户和管理员进行身份验证。我还想为用户和管理员使用两个不同的登录端点以及两个不同的实体和表。

如何做到这一点或者我应该做什么?

更新:

我认为我应该在 oauth_client_details 中创建 2 个具有 2 个不同 grant_types 的 OAuth 客户端,并为用户和管理员创建 2 个 AbstractTokenGranters

我已经有一个自定义的AbstractTokenGranter,用于对用户进行身份验证,如下所示:

//getOAuth2Authentication()
User user = userService.getUserByPhone(username);

if(user == null)
throw new BadCredentialsException("Bad credentials");

Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(Long.toString(user.getId()), password)
);
//I use Long.toString(user.getId()) because some users use FB instead of the phone,
//so I have one more `AbstractTokenGranter` for social networks,
//I don't mention about it in this post, so don't be confused

据我了解,AuthenticationManager 调用 UserDetailsS​​ervice,现在看起来像这样:

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

UserDetails user = userRepository.findById(Long.parseLong(username)).orElseThrow(
() -> new UsernameNotFoundException("User not found with id : " + id)
);

return user;
}

但是,如果我为管理员再创建一个 AbstractTokenGranter,那么当前的 UserDetailsS​​ervice 将不知道它收到的是谁的 ID - 管理员 ID 或用户 ID。

作为一种解决方案,我认为我需要为管理员再创建一个UserDetailsS​​ervice。但是我如何使用多个UserDetailsS​​ervice?另外,也许我应该使用完全不同的方案?

最佳答案

<security:http pattern="/oauth/token" use-expressions="true" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<security:intercept-url pattern="/**" method="GET" access="ROLE_DENY"/>
<security:intercept-url pattern="/**" method="PUT" access="ROLE_DENY"/>
<security:intercept-url pattern="/**" method="DELETE" access="ROLE_DENY"/>
<security:intercept-url pattern="/oauth/token" access="permitAll"/>
<security:anonymous enabled="false"/>
<security:http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<!-- include this only if you need to authenticate clients via request
parameters -->
<security:custom-filter ref="contentTypeFilter" before="BASIC_AUTH_FILTER"/>
<security:custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER"/>


<security:access-denied-handler ref="oauthAccessDeniedHandler"/>
<security:csrf disabled="true"/>
</security:http>

您可以定义自定义 clientDetailService 并重写 loadUserByUserName 方法。是否可以查询不同的表和授权取决于您,也可以更改结构。这就是我可以说的,无需更多描述

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
ClientDetails clientDetails;
try {
clientDetails = clientDetailsService.loadClientByClientId(username);
} catch (NoSuchClientException e) {
throw new UsernameNotFoundException(e.getMessage(), e);
}
String clientSecret = clientDetails.getClientSecret();
if (clientSecret== null || clientSecret.trim().length()==0) {
clientSecret = emptyPassword;
}
return new User(username, clientSecret, clientDetails.getAuthorities());
}

可以修改这部分来改变结构:>authentication-manager-ref="clientAuthenticationManager"

如果您不使用基于 xml 的,您可以检查注释基链接: https://www.baeldung.com/spring-security-authentication-with-a-database

关于java - 使用 Spring Security OAuth2 验证不同的用户类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57400607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com