将自定义 UserDetailsS​​ervice 添加到 Spring Security OAuth2 应用程序 [英] Add custom UserDetailsService to Spring Security OAuth2 app

查看:22
本文介绍了将自定义 UserDetailsS​​ervice 添加到 Spring Security OAuth2 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将下面的自定义 UserDetailsS​​ervice 添加到 这个 Spring OAuth2 示例?

How do I add the custom UserDetailsService below to this Spring OAuth2 sample?

默认user 和默认password 定义在application.properties 文件的authserver 应用程序.

The default user with default password is defined in the application.properties file of the authserver app.

但是,我想将以下自定义 UserDetailsS​​ervice 添加到 authserver 应用程序的demo 用于测试目的:

However, I would like to add the following custom UserDetailsService to the demo package of the authserver app for testing purposes:

package demo;

import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Service;

@Service
class Users implements UserDetailsManager {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String password;
        List<GrantedAuthority> auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER");
        if (username.equals("Samwise")) {
            auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_HOBBIT");
            password = "TheShire";
        }
        else if (username.equals("Frodo")){
            auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_HOBBIT");
            password = "MyRing";
        }
        else{throw new UsernameNotFoundException("Username was not found. ");}
        return new org.springframework.security.core.userdetails.User(username, password, auth);
    }

    @Override
    public void createUser(UserDetails user) {// TODO Auto-generated method stub
    }

    @Override
    public void updateUser(UserDetails user) {// TODO Auto-generated method stub
    }

    @Override
    public void deleteUser(String username) {// TODO Auto-generated method stub
    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean userExists(String username) {
        // TODO Auto-generated method stub
        return false;
    }
}

如您所见,这个 UserDetailsS​​ervice 还不是 autowired,它故意使用不安全的密码,因为它仅用于测试目的.

As you can see, this UserDetailsService is not autowired yet, and it purposely uses insecure passwords because it is only designed for testing purposes.

GitHub 示例应用程序,以便用户可以使用 password=TheShireusername=Samwiseusername=Frodo 的身份登录 with password=MyRing? 是否需要对 AuthserverApplication.java 或其他地方?

What specific changes need to be made to the GitHub sample app so that a user can login as username=Samwise with password=TheShire, or as username=Frodo with password=MyRing? Do changes need to be made to AuthserverApplication.java or elsewhere?

建议:

Spring OAuth2 开发人员指南说使用 GlobalAuthenticationManagerConfigurer 全局配置 UserDetailsS​​ervice.然而,在谷歌上搜索这些名字产生的结果并不那么有用.

The Spring OAuth2 Developer Guide says to use a GlobalAuthenticationManagerConfigurer to configure a UserDetailsService globally. However, googling those names produces less than helpful results.

此外,另一个使用内部 spring 安全性 INSTEAD OF OAuth 的应用程序使用以下语法来连接 UserDetailsS​​ervice,但我不确定如何将其语法调整为当前 OP:

Also, a different app that uses internal spring security INSTEAD OF OAuth uses the following syntax to hook up the UserDetailsService, but I am not sure how to adjust its syntax to the current OP:

@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    private Users users;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(users);
    }
}

我尝试在 OAuth2AuthorizationConfig 中使用 @AutowireUsers 连接到 AuthorizationServerEndpointsConfigurer,如下所示:

I tried using @Autowire inside the OAuth2AuthorizationConfig to connect Users to the AuthorizationServerEndpointsConfigurer as follows:

@Autowired//THIS IS A TEST
private Users users;//THIS IS A TEST

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
   endpoints.authenticationManager(authenticationManager)
        .accessTokenConverter(jwtAccessTokenConverter())
        .userDetailsService(users)//DetailsService)//THIS LINE IS A TEST
        ;
}

但是 Spring Boot 日志显示没有找到用户 Samwise,这意味着 UserDetailsS​​ervice 没有成功连接.以下是 Spring Boot 日志的相关摘录:

But the Spring Boot logs indicate that the user Samwise was not found, which means that the UserDetailsService was not successfully hooked up. Here is the relevant excerpt from the Spring Boot logs:

2016-04-20 15:34:39.998 DEBUG 5535 --- [nio-9999-exec-9] o.s.s.a.dao.DaoAuthenticationProvider    :  
        User 'Samwise' not found
2016-04-20 15:34:39.998 DEBUG 5535 --- [nio-9999-exec-9]   
        w.a.UsernamePasswordAuthenticationFilter :  
        Authentication request failed:  
        org.springframework.security.authentication.BadCredentialsException:  
        Bad credentials

我还能尝试什么?

推荐答案

我在使用 Spring Security 开发 oauth 服务器时遇到了类似的问题.我的情况略有不同,因为我想添加一个 UserDetailsS​​ervice 来验证刷新令牌,但我认为我的解决方案也会对您有所帮助.

I ran into a similar issue when developing my oauth server with Spring Security. My situation was slightly different, as I wanted to add a UserDetailsService to authenticate refresh tokens, but I think my solution will help you as well.

和您一样,我首先尝试使用 AuthorizationServerEndpointsConfigurer 指定 UserDetailsS​​ervice,但这不起作用.我不确定这是错误还是设计使然,但是需要在 AuthenticationManager 中设置 UserDetailsS​​ervice 以便各种 oauth2 类找到它.这对我有用:

Like you, I first tried specifying the UserDetailsService using the AuthorizationServerEndpointsConfigurer, but this does not work. I'm not sure if this is a bug or by design, but the UserDetailsService needs to be set in the AuthenticationManager in order for the various oauth2 classes to find it. This worked for me:

@Configuration
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  Users userDetailsService;

  @Autowired
  public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
    // other stuff to configure your security
  }

}

我认为如果您从第 73 行开始更改以下内容,它可能对您有用:

I think if you changed the following starting at line 73, it may work for you:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.parentAuthenticationManager(authenticationManager)
        .userDetailsService(userDetailsService);
}

您当然还需要在 WebSecurityConfigurerAdapter

我想提的其他事情:

  1. 这可能是特定于版本的,我使用的是 spring-security-oauth2 2.0.12
  2. 我无法引用任何来源说明为什么会这样,我什至不确定我的解决方案是真正的解决方案还是黑客.
  3. 指南中提到的 GlobalAuthenticationManagerConfigurer 几乎肯定是一个错字,我在 Spring 的任何源代码中都找不到该字符串.
  1. This may be version specific, I'm on spring-security-oauth2 2.0.12
  2. I can't cite any sources for why this is the way it is, I'm not even sure if my solution is a real solution or a hack.
  3. The GlobalAuthenticationManagerConfigurer referred to in the guide is almost certainly a typo, I can't find that string anywhere in the source code for anything in Spring.

这篇关于将自定义 UserDetailsS​​ervice 添加到 Spring Security OAuth2 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆