Java Spring Boot OAuth 2-授权服务器不返回令牌,不正确的凭据时不会出现40x状态错误,使用正确的凭据可以正常工作

时间:2018-09-27 15:16:29

标签: java spring spring-boot oauth-2.0

我正在使用包含用户详细信息的Postgres db在Spring Boot上创建OAuth服务器。

当我提供正确的用户名和密码[200 OK]时,身份验证请求工作正常,我可以按预期取回身份验证承载令牌,但是如果凭据错误,代码将进入连续循环而不返回任何响应。它会不断调用UserDetails Service的loadUserByUsername方法,并且即使抛出错误也不会中断。

下面是涉及的不同组件的代码片段。如果有人可以通过查看下面的代码来分享自己的知识,那么我在哪里做错了,那将非常有帮助。

授权服务器配置

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

  @Autowired
  private AuthenticationManager authenticationManager;

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.tokenKeyAccess("permitAll()")
      .checkTokenAccess("isAuthenticated()");
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
      .withClient("my-trusted-client")
      .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
      .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
      .scopes("read", "write", "trust")
      .resourceIds("myResource")
      .secret("{noop}secret")
      .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
      refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
}

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  endpoints.authenticationManager(authenticationManager);
  }
}

资源服务器配置

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {


  @Autowired
  private PasswordEncoder userPasswordEncoder; 

  @Override
  @Bean
  public AuthenticationManager authenticationManagerBean() throws Exception {
      return super.authenticationManagerBean();
  }

  @Autowired
  private CustomUserDetailsService customUserDetailsService;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.requestMatchers()
        .antMatchers("/login", "/oauth/authorize")
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
    .formLogin()
    .permitAll();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.parentAuthenticationManager(authenticationManagerBean())
        .userDetailsService(customUserDetailsService)
        .passwordEncoder(userPasswordEncoder);
  }
}

角色实体

@Entity
@Table(name="roles")
public class Role {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="role_id")
    private int roleId;

    @Column(name="role")
    private String role;

    public Role() {}

    public int getRoleId() {
        return roleId;
    }

    public void setRoleId(int roleId) {
        this.roleId = roleId;
    }

    public String getRole() {
        return role;
    }

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


}

用户实体

@Entity
@Table(name="users")
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="user_id")
    private int id;

    @Column
    private String email;

    @Column
    private String name;

    @Column
    private String password;

    @Column
    private String lastName;

    @Column
    private String active;

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
//  @JoinTable(name="user_role",
//      joinColumns = @JoinColumn(name="user_id"),
//      inverseJoinColumns= @JoinColumn(name="role_id")
//      
//  )
    @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;

    public User() { }

    public User(User users) {
        this.active = users.active;
        this.email = users.email;
        this.id = users.id;
        this.lastName = users.lastName;
        this.name = users.name;
        this.password = users.password;
        this.roles = users.roles;
    }


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getEmail() {
        return email;
    }


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


    public String getName() {
        return name;
    }


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


    public String getPassword() {
        return password;
    }


    public void setPassword(String password) {
        this.password = password;
    }


    public String getLastName() {
        return lastName;
    }


    public void setLastName(String lastName) {
        this.lastName = lastName;
    }


    public String getActive() {
        return active;
    }


    public void setActive(String active) {
        this.active = active;
    }


    public Set<Role> getRoles() {
        return roles;
    }


    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }



}

自定义用户详细信息实体

public class CustomUserDetails implements UserDetails {

  private String username;
  private String password;
  private Collection authorities;

  public CustomUserDetails(User user) {
    this.username = user.getName();
    this.password = user.getPassword();
    this.authorities = user.getRoles().stream()
        .map(role -> new SimpleGrantedAuthority("ROLE_"+role.getRole()))
        .collect(Collectors.toList());
  }

  @Override
  public Collection getAuthorities() {
    return authorities;
  }

  @Override
  public String getPassword() {
    return password;
  }

  @Override
  public String getUsername() {
    return username;
  }

  @Override
  public boolean isAccountNonExpired() {
    return true;
  }

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

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

  @Override
  public boolean isEnabled() {
    return true;
  }
}

用户存储库

public interface UserRepository extends JpaRepository<User, Integer>{

    public Optional<User> findByName(String username);
}

自定义用户详细信息服务Impl

@Service
public class CustomUserDetailsService implements UserDetailsService {

  @Autowired
  private UserRepository userRepository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    System.out.println(username); ***// this keeps printing endless times in case of bad credentials***
      Optional<User> user = userRepository.findByName(username);

    return new CustomUserDetails(
                user.orElseThrow(
                        () -> new UsernameNotFoundException("User not found")
                    )
            );
  }
}

询问是否有人可以干预,让我知道我要去哪里了。我认为这也可能是一个非常小的/愚蠢的错误。寻求您的帮助。预先感谢。

PS:这是我遵循的教程的链接-> https://thecuriousdev.org/spring-security-oauth2

0 个答案:

没有答案