Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自定义登录界面以及修改授权码模式授权流程 #91

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Java CI

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn package --file pom.xml
5 changes: 5 additions & 0 deletions auth/authorization-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<version>2.9.9.2</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
//update by joe_chen add granter
.tokenGranter(tokenGranter(endpoints));

endpoints.pathMapping("/oauth/confirm_access", "/custom/confirm_access");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.springboot.auth.authorization.config;

import com.springboot.auth.authorization.oauth2.config.MobileLoginAuthenticationSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
Expand All @@ -22,62 +23,72 @@
@EnableWebSecurity
public class WebServerSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;

@Autowired
@Qualifier("mobileUserDetailsService")
private UserDetailsService mobileUserDetailsService;
@Autowired
@Qualifier("mobileUserDetailsService")
private UserDetailsService mobileUserDetailsService;

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
@Autowired
private MobileLoginAuthenticationSecurityConfig mobileLoginAuthenticationSecurityConfig;

/**
* 注入自定义的userDetailsService实现,获取用户信息,设置密码加密方式
*
* @param authenticationManagerBuilder
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
// 设置手机验证码登陆的AuthenticationProvider
authenticationManagerBuilder.authenticationProvider(mobileAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/actuator/**","/auth/login","/sc/login","/mobile/login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/login")
.loginProcessingUrl("/sc/login")
.permitAll()
.and()
.apply(mobileLoginAuthenticationSecurityConfig);
}

/**
* 将 AuthenticationManager 注册为 bean , 方便配置 oauth server 的时候使用
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 注入自定义的userDetailsService实现,获取用户信息,设置密码加密方式
*
* @param authenticationManagerBuilder
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
// 设置手机验证码登陆的AuthenticationProvider
authenticationManagerBuilder.authenticationProvider(mobileAuthenticationProvider());
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/** 将 AuthenticationManager 注册为 bean , 方便配置 oauth server 的时候使用 */
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

/**
* 创建手机验证码登陆的AuthenticationProvider
*
* @return mobileAuthenticationProvider
*/
@Bean
public MobileAuthenticationProvider mobileAuthenticationProvider() {
MobileAuthenticationProvider mobileAuthenticationProvider = new MobileAuthenticationProvider(this.mobileUserDetailsService);
mobileAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return mobileAuthenticationProvider;
}
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

/**
* 创建手机验证码登陆的AuthenticationProvider
*
* @return mobileAuthenticationProvider
*/
@Bean
public MobileAuthenticationProvider mobileAuthenticationProvider() {
MobileAuthenticationProvider mobileAuthenticationProvider =
new MobileAuthenticationProvider(this.mobileUserDetailsService);
mobileAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return mobileAuthenticationProvider;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.springboot.auth.authorization.oauth2.config;

import com.springboot.auth.authorization.oauth2.filter.MobileLoginAuthenticationFilter;
import com.springboot.auth.authorization.oauth2.granter.MobileAuthenticationProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
* @author :zwy
*/
@Slf4j
@Configuration
public class MobileLoginAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

@Autowired
private MobileAuthenticationProvider mobileAuthenticationProvider;

@Override
public void configure(HttpSecurity http) throws Exception {
MobileLoginAuthenticationFilter mobileLoginAuthenticationFilter = new MobileLoginAuthenticationFilter();
mobileLoginAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
mobileLoginAuthenticationFilter.setAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler());

SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();
simpleUrlAuthenticationFailureHandler.setDefaultFailureUrl("/auth/login?error");
mobileLoginAuthenticationFilter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler);

http.authenticationProvider(mobileAuthenticationProvider).addFilterAfter(mobileLoginAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.springboot.auth.authorization.oauth2.filter;

import com.springboot.auth.authorization.oauth2.granter.MobileAuthenticationToken;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* @author :zwy
*/
@Slf4j
@Data
public class MobileLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

private Boolean postOnly = true;

public final static String MOBILE_NUMBER = "mobile";
public final static String MOBILE_CODE = "code";

private String numberParameter = MOBILE_NUMBER;
private String codeParameter = MOBILE_CODE;

public MobileLoginAuthenticationFilter(){
super(new AntPathRequestMatcher("/mobile/login", "POST"));
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {

if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}

String mobile = obtainMobile(request);
String code = obtainCode(request);
if (mobile==null){
mobile = "";
}
if (code==null){
code = "";
}

mobile = mobile.trim();
code = code.trim();

MobileAuthenticationToken authRequest =
new MobileAuthenticationToken(new UsernamePasswordAuthenticationToken(mobile, code));

setDetails(request, authRequest);

return this.getAuthenticationManager().authenticate(authRequest);
}

protected String obtainMobile(HttpServletRequest request){
return request.getParameter(numberParameter);
}

protected String obtainCode(HttpServletRequest request){
return request.getParameter(codeParameter);
}

protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}

public void setNumberParameter(String numberParameter) {
Assert.hasText(numberParameter, "phone number parameter must not be empty or null");
this.numberParameter = numberParameter;
}

public void setCodeParameter(String codeParameter) {
Assert.hasText(codeParameter, "code parameter must not be empty or null");
this.codeParameter = codeParameter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.springboot.auth.authorization.rest;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
* @author :zwy
*/
@Controller
@SessionAttributes("authorizationRequest")
@Slf4j
public class GrantController {

@RequestMapping("/custom/confirm_access")
public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception {

AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");
ModelAndView view = new ModelAndView();
view.setViewName("sc-grant");

view.addObject("clientId", authorizationRequest.getClientId());
view.addObject("scopes",authorizationRequest.getScope());

return view;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.springboot.auth.authorization.rest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
* @author :zwy
*/
@Controller
public class LoginController {

@GetMapping("/auth/login")
public String toLogin(){

//授权码模式使用手机登录,返回/sc-mobile-login

return "/sc-login";
}
}
4 changes: 4 additions & 0 deletions auth/authorization-server/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ eureka:
defaultZone: http://${EUREKA_ZONE_HOST:localhost}:${EUREKA_ZONE_PORT:8761}/eureka/

spring:
thymeleaf:
prefix: classpath:/static/
suffix: .html
cache: false
application:
name: authorization-server
rabbitmq:
Expand Down
Loading