SpringCloud OAuth2 + JWT 认证授权(二)资源服务器

系列文章

Spring Cloud oAuth2(一)搭建授权服务器以及访问

Spring Cloud oAuth2(二)搭建资源服务器以及测试

SpringCloud OAuth2 + JWT 认证授权(一)授权服务器

SpringCloud OAuth2 + JWT 认证授权(二)资源服务器

目录

简介

实体对象

资源服务器配置

访问配置

登陆逻辑

总结


简介

这里对个人在搭建第三方授权服务的过程中,遇到的问题进行总结。如果不是非必要的第三方登录,单个JWT就能满足简单的授权验证的,不过相关的验证和授权需要自己去写。本文源码:源码地址

实体对象

  • 角色
@Data
@Entity
public class Role implements GrantedAuthority, Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false,unique = true)
    private String name;

    @Override
    public String getAuthority() {
        return name;
    }
}
  • 用户以及与角色的对应关系
@Data
@Entity
public class User implements UserDetails, Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false,unique = true)
    private String username;

    private String password;

    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(
            name = "user_role",
            joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name="role_id",referencedColumnName = "id")}
    )
    List<Role> authorities;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

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

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

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

    @Override
    public boolean isEnabled() {
        return true;
    }
}
  • 授权返回类型
@Data
public class MyJWT {

    String access_token;
    String token_type;
    String expires_in;
    String scope;
}

资源服务器配置

  • jwt密码加密方式以及密码转换方式配置
@Configuration
public class JwtConfig {


    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public TokenStore tokenStore()
    {
        return  new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter()
    {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        ClassPathResource resource = new ClassPathResource("public.cert");
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
            String publicKey = bufferedReader.lines().collect(Collectors.joining("\n"));
            converter.setVerifierKey(publicKey);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return converter;
    }

}

注意:

  1. 这里获取公钥的方式要正确(换行和不换行)
  2. setVerifierKey和seySignKey区别在于非对称和对称加密
  • 资源服务器配置
@EnableResourceServer
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    public TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/user/login","/user/one").permitAll()
            .anyRequest().authenticated();
    }

}

访问配置

  • feign配置(重试次数,超时时间等)
@Configuration
public class FeignConfig {

    @Bean
    public Retryer feignRetryer()
    {
        return  new Retryer.Default(100,1000,5);
    }
}
  • feign访问服务

//feign调用serviceId和熔断器
@FeignClient(value = "auth-service",fallback = FeignHystrix.class,configuration = FeignConfig.class)
public interface AuthService {

    @PostMapping("/oauth/token")
    MyJWT getToken(@RequestParam("client_id") String client_id, @RequestParam("client_secret")String client_secret,@RequestParam("username")String username,@RequestParam("password")String password, @RequestParam("grant_type") String grant_type);

}
  • hystrix熔断器处理
//熔断器处理
@Component
public class FeignHystrix implements AuthService {

    @Override
    public MyJWT getToken(String client_id, String client_secret, String username, String password, String grant_type) {
        System.out.println("异常");
        return null;
    }
}

登陆逻辑

@Service
public class UserService {

   @Autowired
   private UserDao userDao;

   @Autowired
   private PasswordEncoder passwordEncoder;

   @Autowired
   private AuthService authService;

   public void addUser(User user)
   {
      user.setPassword(passwordEncoder.encode(user.getPassword()));
      userDao.save(user);
   }

   public MyResponse<MyJWT> login(User user)
   {
      User findUser = userDao.findByUsername(user.getUsername());
      if(null==findUser)
      {
         throw new MyException("用户名错误!",501);
      }
      else if(!passwordEncoder.matches(user.getPassword(),findUser.getPassword()))
      {
         throw new MyException("密码错误!",502);
      }
      MyJWT token = authService.getToken("kevin", "kevin12345", user.getUsername(),user.getPassword(),"password");
      return new MyResponse<MyJWT>(token);
   }

总结

个人在玩儿的时候将授权模式改成了client_credentials客户端方式,还添加了权限管控,导致访问一直显示无法访问,懵逼了很久,后来才恍然大悟,客户端方式并没有进入数据库获取权限,所以权限一直为空,汗。。。。,对了,当前代码并不完善,需要完整代码的请访问源码地址。

发布了7 篇原创文章 · 获赞 1 · 访问量 395

猜你喜欢

转载自blog.csdn.net/qq_35427539/article/details/103866664