Spring Security Oauth2.0 实现自定义认证授权

定义手机号登录令牌

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

/**

 * @author lengleng

 * @date 2018/1/9

 * 手机号登录令牌

 */

public class MobileAuthenticationToken extends AbstractAuthenticationToken {

 

  private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

 

  private final Object principal;

 

  public MobileAuthenticationToken(String mobile) {

    super(null);

    this.principal = mobile;

    setAuthenticated(false);

  }

 

  public MobileAuthenticationToken(Object principal,

                   Collection<? extends GrantedAuthority> authorities) {

    super(authorities);

    this.principal = principal;

    super.setAuthenticated(true);

  }

 

  public Object getPrincipal() {

    return this.principal;

  }

 

  @Override

  public Object getCredentials() {

    return null;

  }

 

  public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

    if (isAuthenticated) {

      throw new IllegalArgumentException(

          "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");

    }

 

    super.setAuthenticated(false);

  }

 

  @Override

  public void eraseCredentials() {

    super.eraseCredentials();

  }

}

手机号登录校验逻辑

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

/**

 * @author lengleng

 * @date 2018/1/9

 * 手机号登录校验逻辑

 */

public class MobileAuthenticationProvider implements AuthenticationProvider {

  private UserService userService;

 

  @Override

  public Authentication authenticate(Authentication authentication) throws AuthenticationException {

    MobileAuthenticationToken mobileAuthenticationToken = (MobileAuthenticationToken) authentication;

    UserVo userVo = userService.findUserByMobile((String) mobileAuthenticationToken.getPrincipal());

 

    UserDetailsImpl userDetails = buildUserDeatils(userVo);

    if (userDetails == null) {

      throw new InternalAuthenticationServiceException("手机号不存在:" + mobileAuthenticationToken.getPrincipal());

    }

 

    MobileAuthenticationToken authenticationToken = new MobileAuthenticationToken(userDetails, userDetails.getAuthorities());

    authenticationToken.setDetails(mobileAuthenticationToken.getDetails());

    return authenticationToken;

  }

 

  private UserDetailsImpl buildUserDeatils(UserVo userVo) {

    return new UserDetailsImpl(userVo);

  }

 

  @Override

  public boolean supports(Class<?> authentication) {

    return MobileAuthenticationToken.class.isAssignableFrom(authentication);

  }

 

  public UserService getUserService() {

    return userService;

  }

 

  public void setUserService(UserService userService) {

    this.userService = userService;

  }

}

登录过程filter处理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

/**

 * @author lengleng

 * @date 2018/1/9

 * 手机号登录验证filter

 */

public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

  public static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";

 

  private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;

  private boolean postOnly = true;

 

  public MobileAuthenticationFilter() {

    super(new AntPathRequestMatcher(SecurityConstants.MOBILE_TOKEN_URL, "POST"));

  }

 

  public Authentication attemptAuthentication(HttpServletRequest request,

                        HttpServletResponse response) throws AuthenticationException {

    if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {

      throw new AuthenticationServiceException(

          "Authentication method not supported: " + request.getMethod());

    }

 

    String mobile = obtainMobile(request);

 

    if (mobile == null) {

      mobile = "";

    }

 

    mobile = mobile.trim();

 

    MobileAuthenticationToken mobileAuthenticationToken = new MobileAuthenticationToken(mobile);

 

    setDetails(request, mobileAuthenticationToken);

 

    return this.getAuthenticationManager().authenticate(mobileAuthenticationToken);

  }

 

  protected String obtainMobile(HttpServletRequest request) {

    return request.getParameter(mobileParameter);

  }

 

  protected void setDetails(HttpServletRequest request,

               MobileAuthenticationToken authRequest) {

    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

  }

 

  public void setPostOnly(boolean postOnly) {

    this.postOnly = postOnly;

  }

 

  public String getMobileParameter() {

    return mobileParameter;

  }

 

  public void setMobileParameter(String mobileParameter) {

    this.mobileParameter = mobileParameter;

  }

 

  public boolean isPostOnly() {

    return postOnly;

  }

}

生产token 位置

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

/**

 * @author lengleng

 * @date 2018/1/8

 * 手机号登录成功,返回oauth token

 */

@Component

public class MobileLoginSuccessHandler implements org.springframework.security.web.authentication.AuthenticationSuccessHandler {

  private Logger logger = LoggerFactory.getLogger(getClass());

  @Autowired

  private ObjectMapper objectMapper;

  @Autowired

  private ClientDetailsService clientDetailsService;

  @Autowired

  private AuthorizationServerTokenServices authorizationServerTokenServices;

 

  @Override

  public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {

    String header = request.getHeader("Authorization");

 

    if (header == null || !header.startsWith("Basic ")) {

      throw new UnapprovedClientAuthenticationException("请求头中client信息为空");

    }

 

    try {

      String[] tokens = extractAndDecodeHeader(header);

      assert tokens.length == 2;

      String clientId = tokens[0];

      String clientSecret = tokens[1];

 

      JSONObject params = new JSONObject();

      params.put("clientId", clientId);

      params.put("clientSecret", clientSecret);

      params.put("authentication", authentication);

 

      ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

      TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "mobile");

      OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);

 

      OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

      OAuth2AccessToken oAuth2AccessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

      logger.info("获取token 成功:{}", oAuth2AccessToken.getValue());

 

      response.setCharacterEncoding(CommonConstant.UTF8);

      response.setContentType(CommonConstant.CONTENT_TYPE);

      PrintWriter printWriter = response.getWriter();

      printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken));

    } catch (IOException e) {

      throw new BadCredentialsException(

          "Failed to decode basic authentication token");

    }

  }

 

  /**

   * Decodes the header into a username and password.

   *

   * @throws BadCredentialsException if the Basic header is not present or is not valid

   *                 Base64

   */

  private String[] extractAndDecodeHeader(String header)

      throws IOException {

 

    byte[] base64Token = header.substring(6).getBytes("UTF-8");

    byte[] decoded;

    try {

      decoded = Base64.decode(base64Token);

    } catch (IllegalArgumentException e) {

      throw new BadCredentialsException(

          "Failed to decode basic authentication token");

    }

 

    String token = new String(decoded, CommonConstant.UTF8);

 

    int delim = token.indexOf(":");

 

    if (delim == -1) {

      throw new BadCredentialsException("Invalid basic authentication token");

    }

    return new String[]{token.substring(0, delim), token.substring(delim + 1)};

  }

}

配置以上自定义

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

//**

 * @author lengleng

 * @date 2018/1/9

 * 手机号登录配置入口

 */

@Component

public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

  @Autowired

  private MobileLoginSuccessHandler mobileLoginSuccessHandler;

  @Autowired

  private UserService userService;

 

  @Override

  public void configure(HttpSecurity http) throws Exception {

    MobileAuthenticationFilter mobileAuthenticationFilter = new MobileAuthenticationFilter();

    mobileAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));

    mobileAuthenticationFilter.setAuthenticationSuccessHandler(mobileLoginSuccessHandler);

 

    MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider();

    mobileAuthenticationProvider.setUserService(userService);

    http.authenticationProvider(mobileAuthenticationProvider)

        .addFilterAfter(mobileAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

  }

}

在spring security 配置 上边定一个的那个聚合配置

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/**

 * @author lengleng

 * @date 2018年01月09日14:01:25

 * 认证服务器开放接口配置

 */

@Configuration

@EnableResourceServer

public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

  @Autowired

  private FilterUrlsPropertiesConifg filterUrlsPropertiesConifg;

  @Autowired

  private MobileSecurityConfigurer mobileSecurityConfigurer;

 

  @Override

  public void configure(HttpSecurity http) throws Exception {

    registry

        .antMatchers("/mobile/token").permissionAll()

        .anyRequest().authenticated()

        .and()

        .csrf().disable();

    http.apply(mobileSecurityConfigurer);

  }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值