java - 同一项目中的 Spring Boot Basic Authentication 和 OAuth2?

标签 java maven spring-boot intellij-idea spring-security

是否可以在我的其余应用程序中对某些端点使用 OAuth2,并对其他一些端点也使用基本身份验证。 它应该都适用于 spring security 版本 2.0.1.RELEASE。我希望有人能进一步帮助我。

最佳答案

是的,可以同时使用基本身份验证和 OAuth2 身份验证,但我怀疑您是否能够轻松设置它,因为 HttpSecurity 的 authenticated() 方法不允许您可以选择哪种身份验证方法 (oauth2Login/formLogin) 有效。

但是,有一种方法可以轻松绕过它:

您可以添加自定义权限,当用户使用基本身份验证连接时,我们称它为 ROLE_BASICAUTH,当用户使用 OAuth2 连接时,我们称它为 ROLE_OAUTH2。这样,您就可以使用

.antMatchers("/endpoint-that-requires-basic-auth").hasRole("BASICAUTH")
.antMatchers("/endpoint-that-requires-oauth2").hasRole("OAUTH2")
    .anyRequest().authenticated()

当他们到达您想要基本身份验证(而不是 OAuth2)的端点时,您检查他们当前的权限,如果不是 BASICAUTH,那么您使他们的 session 无效,您显示一个登录表单 没有 OAuth2(强制他们使用基本身份验证)。

这样做的缺点是您需要同时实现自定义 UserDetailsS​​ervice 和自定义 OAuth2UserService...

但这其实并不难:

@Service
public class UserService extends DefaultOAuth2UserService implements UserDetailsService {

    // ...

    @Override
    public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
        OAuth2User user = super.loadUser(oAuth2UserRequest);

        Map<String, Object> attributes = user.getAttributes();
        Set<GrantedAuthority> authoritySet = new HashSet<>(user.getAuthorities());
        String userNameAttributeName = oAuth2UserRequest.getClientRegistration().getProviderDetails()
                .getUserInfoEndpoint().getUserNameAttributeName();

        authoritySet.add(new SimpleGrantedAuthority("ROLE_OAUTH2"));

        return new DefaultOAuth2User(authoritySet, attributes, userNameAttributeName);
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails user = getUserFromDatabase(username); // you'll need to provide that method (where are the username/password stored?)
        if (user == null) { // UserDetailsService doesn't allow loadUserByUsername to return null, so throw exception
            throw new UsernameNotFoundException("Couldn't find user with username '"+username+"'");
        }
        // add ROLE_BASICAUTH (you might need a custom UserDetails implementation here, because by defaut, UserDetails.getAuthorities() is immutable (I think, I might be a liar)
        return user;
    }

}

请注意,这是一个粗略的实现,因此您还必须自己解决一些问题。

您也可以使用我制作的这个存储库 https://github.com/TwinProduction/spring-security-oauth2-client-example/tree/master/custom-userservice-sample作为自定义 OAuth2UserService 的指南

祝你好运。

关于java - 同一项目中的 Spring Boot Basic Authentication 和 OAuth2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50061662/

相关文章:

java - 调试 Maven Eclipse 项目并单步调试代码?

java - 无法避免 hibernate 记录 SQL 以使用 Spring Boot 和 Logback 进行控制台

java - QueryDsl MongoDB - 访问深度嵌套对象进行查询

java - 使用 multipart/form-data 或 multipart/mixed 在获取 JSON 和文件时让 Spring 进行映射

java - 串口读取 - 错误 : EXCEPTION_ACCESS_VIOLATION - C [rxtxSerial. dll+0x5b00]

java - MapStruct 避免返回对象创建

java - 强制 maven spring boot 项目使用旧版本的依赖项,而不是另一个依赖项的新版本

java - 将外部文件夹添加到可运行 jar 中的 ClassPath

java - 如何为项目列表设置默认值?

java - 为什么我的 REST API 在嵌套对象上返回空白 JSON?