SpringCloud微服务实战系列(十八)Ouath2在真实场景中的应用之授权服务器
一、概述
在《SpringCloud微服务实战系列(十七)Ouath2在真实场景中的应用之资源服务器》]中 已经介绍了资源服务器是如何搭建的。
本篇就是对Oauth2的实际应用方法的授权服务器搭建方式进行介绍。
如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。
在Spring Oauth2中,Oauth2的使用过程中将角色分为三种:ResourceServer,AuthorizationServer,OauthClient.
由于篇幅较大,这里将Oauth2的搭建分成三个部分。本篇先介绍AuthorizationServer。
二、授权服务器
授权服务器就是Oauth2的认证中心。管理token、client等,需要配置的东西很多。
下面讲述下这个过程是怎样的。
2.1 引入依赖
需要引入spring-boot-starter-web、spring-cloud-starter-security和spring-security-oauth2和mybatis相关jar包.
依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${security.oauth2.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
</dependencies>
这里,security.oauth2.version我选择的是2.3.5.RELEASE。
2.2 配置文件
这里使用yaml文件写配置,配置文件application.yml:
application.yml:
server:
port: 8182
spring:
main:
allow-bean-definition-overriding: true
profiles:
active: loc
application:
name: oauthAuth
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
这里
- 应用名称为oauthAuth
- allow-bean-definition-overriding为true,是因为要定义新的bean,覆盖默认的。
application-loc.yml:
env: loc
spring:
datasource:
type: org.apache.commons.dbcp2.BasicDataSource
dbcp2:
max-wait-millis: 60000
min-idle: 20
initial-size: 2
connection-properties: characterEncoding=utf8
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: true
test-on-return: false
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: cff
password: 123456
这里配置的是数据库及数据源信息
2.3 启动
使用main直接启动即可。需要使用注解@EnableAuthorizationServer表明它是授权服务器。
OauthAuthApplication:
package cn.pomit.springbootwork.oauthauth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
@EnableAuthorizationServer
@SpringBootApplication
public class OauthAuthApplication {
public static void main(String[] args) {
SpringApplication.run(OauthAuthApplication.class, args);
}
}
2.4 安全控制配置
这个安全控制,只是普通的Spring Security的安全配置。
需要继承WebSecurityConfigurerAdapter,并加上@EnableWebSecurity。
AccessSecurityConfiguration如下:
package cn.pomit.springbootwork.oauthauth.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import cn.pomit.springbootwork.oauthauth.handler.AjaxAuthFailHandler;
import cn.pomit.springbootwork.oauthauth.handler.AjaxLogoutSuccessHandler;
import cn.pomit.springbootwork.oauthauth.handler.AuthSuccessHandler;
import cn.pomit.springbootwork.oauthauth.handler.UnauthorizedEntryPoint;
import cn.pomit.springbootwork.oauthauth.provider.SimpleAuthenticationProvider;
@Configuration
@EnableWebSecurity
public class AccessSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private SimpleAuthenticationProvider simpleAuthenticationProvider;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(simpleAuthenticationProvider);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(new UnauthorizedEntryPoint()).and()
.csrf().disable()
.authorizeRequests().antMatchers("/oauth/**").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/index.html").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/api/**").authenticated()
.and().formLogin()
.loginPage("/login.html").usernameParameter("userName").passwordParameter("userPwd")
.loginProcessingUrl("/login").successHandler(new AuthSuccessHandler())
.failureHandler(new AjaxAuthFailHandler()).and()
.logout().logoutUrl("/logout")
.logoutSuccessHandler(new AjaxLogoutSuccessHandler());
}
}
其中,SimpleAuthenticationProvider是处理用户名密码校验的。
UnauthorizedEntryPoint、AuthSuccessHandler、AjaxAuthFailHandler、AjaxLogoutSuccessHandler这些是对认证成功、失败等的处理方法,后面会贴出来,这里先不细讲了。
注意: /oauth/**
路径要放开
2.5 授权服务器配置
- 因为授权服务器默认存储的客户端信息默认都是基于内存的,然而,实际应用中都是基于数据库的,因此,我们要把它改造为数据库中获取,比如:
- Oauth2的授权码是6位,实在是有点短,可以重写AuthorizationCodeServices,将它变成更长位数。
- PasswordEncoder需要指定,如果不需要对密码进行处理,可以使用NoOpPasswordEncoder。
AuthorizationServerConfiguration:
package cn.pomit.springbootwork.oauthauth.config;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import cn.pomit.springbootwork.oauthauth.domain.OauthClientInfo;
import cn.pomit.springbootwork.oauthauth.service.OauthClientService;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authorizationCodeServices")
private AuthorizationCodeServices authorizationCodeServices;
@Autowired
OauthClientService oauthClientService;
@Bean
public PasswordEncoder noOpPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
/**
* 可以在这里将客户端数据替换成数据库配置。
*
* @return
*/
@Bean
public ClientDetailsService clientDetailsService() {
InMemoryClientDetailsService inMemoryClientDetailsService = new InMemoryClientDetailsService();
Map<String, ClientDetails> clientDetailsStore = new HashMap<>();
List<OauthClientInfo> clientList = oauthClientService.findAll();
for (OauthClientInfo item : clientList) {
BaseClientDetails baseClientDetails = new BaseClientDetails();
baseClientDetails.setClientId(item.getClientId());
baseClientDetails.setClientSecret(item.getClientSecret());
baseClientDetails.setAccessTokenValiditySeconds(item.getAccessTokenTime());
baseClientDetails.setRefreshTokenValiditySeconds(item.getRefreshTokenTime());
Set<String> salesWords = new HashSet<String>(Arrays.asList(item.getRedirectUrls().split(",")));
baseClientDetails.setRegisteredRedirectUri(salesWords);
List<String> scope = Arrays.asList(item.getScopes().split(","));
baseClientDetails.setScope(scope);
List<String> authorizedGrantTypes = Arrays.asList(item.getAuthorizedGrantTypes().split(","));
baseClientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
clientDetailsStore.put(item.getClientId(), baseClientDetails);
}
inMemoryClientDetailsService.setClientDetailsStore(clientDetailsStore);
return inMemoryClientDetailsService;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authorizationCodeServices(authorizationCodeServices);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("permitAll()").allowFormAuthenticationForClients();
}
}
2.6 授权码长度控制AuthorizationCodeServices
InMemoryAuthorizationCodeServices :
package cn.pomit.springbootwork.oauthauth.token;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
import org.springframework.stereotype.Service;
@Service("authorizationCodeServices")
public class InMemoryAuthorizationCodeServices extends RandomValueAuthorizationCodeServices {
protected final ConcurrentHashMap<String, OAuth2Authentication> authorizationCodeStore = new ConcurrentHashMap<String, OAuth2Authentication>();
private RandomValueStringGenerator generator = new RandomValueStringGenerator(16);
@Override
protected void store(String code, OAuth2Authentication authentication) {
this.authorizationCodeStore.put(code, authentication);
}
@Override
public OAuth2Authentication remove(String code) {
OAuth2Authentication auth = this.authorizationCodeStore.remove(code);
return auth;
}
@Override
public String createAuthorizationCode(OAuth2Authentication authentication) {
String code = generator.generate();
store(code, authentication);
return code;
}
}
它和Spring的InMemoryAuthorizationCodeServices没多大区别,区别在于RandomValueStringGenerator对象构造函数参数是16。
2.7 用户密码校验
SimpleAuthenticationProvider用来控制用户的校验,属于SpringSecurity的常用写法。
SimpleAuthenticationProvider:
package cn.pomit.springbootwork.oauthauth.provider;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Component;
import cn.pomit.springbootwork.oauthauth.domain.UserInfo;
import cn.pomit.springbootwork.oauthauth.service.UserInfoService;
@Component
public class SimpleAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserInfoService userInfoService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userName = authentication.getPrincipal().toString();
UserInfo user = userInfoService.getUserInfoByUserName(userName);
if (user == null) {
throw new BadCredentialsException("查无此用户");
}
if (user.getPasswd() != null && user.getPasswd().equals(authentication.getCredentials())) {
Collection<? extends GrantedAuthority> authorities = null;
if (user.getUserType() != null && user.getUserType().equals("2")) {
authorities = AuthorityUtils
.createAuthorityList("ROLE_ADMIN");
} else {
authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
}
return new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPasswd(), authorities);
} else {
throw new BadCredentialsException("用户名或密码错误。");
}
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
2.8 Service、Mapper及一些简单的Handler
这里是我用到的一些Service、Mapper及简单的Handler,可以根据自己的需要随便改。
2.8.1 Service
OauthClientService:
package cn.pomit.springbootwork.oauthauth.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.pomit.springbootwork.oauthauth.domain.OauthClientInfo;
import cn.pomit.springbootwork.oauthauth.mapper.TOauthClientMapper;
@Service
public class OauthClientService {
@Autowired
TOauthClientMapper tOauthClientMapper;
public List<OauthClientInfo> findAll() {
return tOauthClientMapper.findAll();
}
}
UserInfoService:
package cn.pomit.springbootwork.oauthauth.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.pomit.springbootwork.oauthauth.domain.UserInfo;
import cn.pomit.springbootwork.oauthauth.mapper.UserInfoMapper;
@Service
public class UserInfoService {
@Autowired
UserInfoMapper userInfoMapper;
public UserInfo getUserInfoByUserName(String userName){
return userInfoMapper.findByUserName(userName);
}
public List<UserInfo> page(int page, int size){
return userInfoMapper.testPageSql(page, size);
}
public List<UserInfo> testTrimSql(UserInfo userInfo){
return userInfoMapper.testTrimSql(userInfo);
}
}
2.8.2 Mapper
TOauthClientMapper:
package cn.pomit.springbootwork.oauthauth.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import cn.pomit.springbootwork.oauthauth.domain.OauthClientInfo;
@Mapper
public interface TOauthClientMapper {
@Select({
"<script>",
"SELECT ",
"client_id as clientId,client_secret as clientSecret,access_token_time as accessTokenTime,refresh_token_time as refreshTokenTime,redirect_urls as redirectUrls,scopes as scopes,authorized_grant_types as authorizedGrantTypes",
"FROM t_oauth_client",
"</script>"})
List<OauthClientInfo> findAll();
}
UserInfoMapper:
package cn.pomit.springbootwork.oauthauth.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import cn.pomit.springbootwork.oauthauth.domain.UserInfo;
@Mapper
public interface UserInfoMapper {
@Select({
"<script>",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
"FROM user_info",
"WHERE user_name = #{userName,jdbcType=VARCHAR}",
"</script>"})
UserInfo findByUserName(@Param("userName") String userName);
@Select({
"<script>",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
"FROM user_info",
"WHERE mobile = #{mobile,jdbcType=VARCHAR}",
"<if test='userType != null and userType != "" '> and user_type = #{userType, jdbcType=VARCHAR} </if>",
"</script>"})
List<UserInfo> testIfSql(@Param("mobile") String mobile,@Param("userType") String userType);
@Select({
"<script>",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
" FROM user_info ",
" WHERE mobile IN (",
" <foreach collection = 'mobileList' item='mobileItem' index='index' separator=',' >",
" #{mobileItem}",
" </foreach>",
" )",
"</script>"})
List<UserInfo> testForeachSql(@Param("mobileList") List<String> mobile);
@Update({
"<script>",
" UPDATE user_info",
" SET ",
" <choose>",
" <when test='userType!=null'> user_type=#{user_type, jdbcType=VARCHAR} </when>",
" <otherwise> user_type='0000' </otherwise>",
" </choose>",
" WHERE user_name = #{userName, jdbcType=VARCHAR}",
"</script>" })
int testUpdateWhenSql(@Param("userName") String userName,@Param("userType") String userType);
@Select({
"<script>",
"<bind name="tableName" value="item.getIdentifyTable()" />",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
"FROM ${tableName}",
"WHERE mobile = #{item.mobile,jdbcType=VARCHAR}",
"</script>"})
public List<UserInfo> testBindSql(@Param("item") UserInfo userInfo);
@Select({
"<script>",
"<bind name="startNum" value="page*pageSize" />",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
"FROM user_info",
"ORDER BY mobile ASC",
"LIMIT #{pageSize} OFFSET #{startNum}",
"</script>"})
public List<UserInfo> testPageSql(@Param("page") int page, @Param("pageSize") int size);
@Select({
"<script>",
"SELECT ",
"user_name as userName,passwd,name,mobile,valid, user_type as userType",
"FROM user_info",
"<trim prefix=" where " prefixOverrides="AND">",
"<if test='item.userType != null and item.userType != "" '> and user_type = #{item.userType, jdbcType=VARCHAR} </if>",
"<if test='item.mobile != null and item.mobile != "" '> and mobile = #{item.mobile, jdbcType=VARCHAR} </if>",
"</trim>",
"</script>"})
public List<UserInfo> testTrimSql(@Param("item") UserInfo userInfo);
@Update({
"<script>",
" UPDATE user_info",
" <set> ",
"<if test='item.userType != null and item.userType != "" '>user_type = #{item.userType, jdbcType=VARCHAR}, </if>",
"<if test='item.mobile != null and item.mobile != "" '> mobile = #{item.mobile, jdbcType=VARCHAR} </if>",
" </set>",
" WHERE user_name = #{item.userName, jdbcType=VARCHAR}",
"</script>" })
public int testSetSql(@Param("item") UserInfo userInfo);
}
2.8.3 Handler
AjaxAuthFailHandler:
package cn.pomit.springbootwork.oauthauth.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.pomit.springbootwork.oauthauth.model.ResultCode;
import cn.pomit.springbootwork.oauthauth.model.ResultModel;
public class AjaxAuthFailHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
if (isAjaxRequest(request)) {
ResultModel rm = new ResultModel(ResultCode.CODE_00014.getCode(), exception.getMessage());
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
mapper.writeValue(response.getWriter(), rm);
} else {
setDefaultFailureUrl("/login.html");
super.onAuthenticationFailure(request, response, exception);
}
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
}
}
AjaxLogoutSuccessHandler:
package cn.pomit.springbootwork.oauthauth.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.pomit.springbootwork.oauthauth.model.ResultCode;
import cn.pomit.springbootwork.oauthauth.model.ResultModel;
public class AjaxLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
if (isAjaxRequest(request)) {
ResultModel rm = new ResultModel(ResultCode.CODE_00000);
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
mapper.writeValue(response.getWriter(), rm);
} else {
super.onLogoutSuccess(request, response, authentication);
}
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
}
}
AuthSuccessHandler:
package cn.pomit.springbootwork.oauthauth.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
public class AuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
RequestCache cache = new HttpSessionRequestCache();
SavedRequest savedRequest = cache.getRequest(request, response);
String url = savedRequest.getRedirectUrl();
response.sendRedirect(url);
}
}
UnauthorizedEntryPoint:
package cn.pomit.springbootwork.oauthauth.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.pomit.springbootwork.oauthauth.model.ResultCode;
import cn.pomit.springbootwork.oauthauth.model.ResultModel;
public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
if (isAjaxRequest(request)) {
ResultModel rm = new ResultModel(ResultCode.CODE_40004);
ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
mapper.writeValue(response.getWriter(), rm);
} else {
response.sendRedirect("/login.html");
}
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
}
}
2.8.4 实体
UserInfo:
package cn.pomit.springbootwork.oauthauth.domain;
public class UserInfo {
private String userName;
private String passwd;
private String name;
private String mobile;
private Integer valid;
private String userType;
public UserInfo() {
}
public UserInfo(UserInfo src) {
this.userName = src.userName;
this.passwd = src.passwd;
this.name = src.name;
this.mobile = src.mobile;
this.valid = src.valid;
}
public UserInfo(String userName, String passwd, String name, String mobile, Integer valid) {
super();
this.userName = userName;
this.passwd = passwd;
this.name = name;
this.mobile = mobile;
this.valid = valid;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getPasswd() {
return passwd;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getMobile() {
return mobile;
}
public void setValid(Integer valid) {
this.valid = valid;
}
public Integer getValid() {
return valid;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getIdentifyTable(){
return "user_info";
}
}
OauthClientInfo:
package cn.pomit.springbootwork.oauthauth.domain;
public class OauthClientInfo {
private String clientId;
private String clientSecret;
private int accessTokenTime;
private int refreshTokenTime;
private String redirectUrls;
private String scopes;
private String authorizedGrantTypes;
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientId() {
return clientId;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getClientSecret() {
return clientSecret;
}
public void setAccessTokenTime(int accessTokenTime) {
this.accessTokenTime = accessTokenTime;
}
public int getAccessTokenTime() {
return accessTokenTime;
}
public void setRefreshTokenTime(int refreshTokenTime) {
this.refreshTokenTime = refreshTokenTime;
}
public int getRefreshTokenTime() {
return refreshTokenTime;
}
public void setRedirectUrls(String redirectUrls) {
this.redirectUrls = redirectUrls;
}
public String getRedirectUrls() {
return redirectUrls;
}
public void setScopes(String scopes) {
this.scopes = scopes;
}
public String getScopes() {
return scopes;
}
public String getAuthorizedGrantTypes() {
return authorizedGrantTypes;
}
public void setAuthorizedGrantTypes(String authorizedGrantTypes) {
this.authorizedGrantTypes = authorizedGrantTypes;
}
}
2.9 测试web
OauthAuthRest:
package cn.pomit.springbootwork.oauthauth.web;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import cn.pomit.springbootwork.oauthauth.model.IpModel;
import cn.pomit.springbootwork.oauthauth.model.ResultModel;
import cn.pomit.springbootwork.oauthauth.util.IPUtil;
@RestController
@RequestMapping("/api")
public class OauthAuthRest {
@RequestMapping(value = "/ip", method = { RequestMethod.GET })
public ResultModel ip(HttpServletRequest request) {
IpModel ipModel = new IpModel();
ipModel.setClientIpAddress(IPUtil.getIpAddr(request));
ipModel.setServerIpAddress(IPUtil.localIp());
return ResultModel.ok(ipModel);
}
@RequestMapping(value = "/userInfo")
public ResultModel userinfo(Principal principal) {
return ResultModel.ok(principal.getName());
}
}
OauthTestRest:
package cn.pomit.springbootwork.oauthauth.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import cn.pomit.springbootwork.oauthauth.model.ResultModel;
@Controller
@RequestMapping("/")
public class OauthTestRest {
@ResponseBody
@RequestMapping(value = "/test/test", method = { RequestMethod.GET })
public ResultModel test() {
return ResultModel.ok("我就是test");
}
@RequestMapping(value = "/", method = { RequestMethod.GET })
public String index() {
return "/index.html";
}
@RequestMapping(value = "/oauth/confirm_access", method = { RequestMethod.GET })
public String oauthAuthorize() {
return "/authorize.html";
}
}
IPUtil:
package cn.pomit.springbootwork.oauthauth.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
public class IPUtil {
/**
* @Description: 获取客户端IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if (ip.equals("127.0.0.1")) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (Exception e) {
e.printStackTrace();
}
ip = inet.getHostAddress();
}
}
// 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
/**
* 获取的是本地的IP地址
*
* @return
*/
public static String localIp() {
String result = "";
try {
InetAddress address = InetAddress.getLocalHost();
result = address.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return result;
}
}
ResultModel:
package cn.pomit.springbootwork.oauthauth.model;
/**
* @author cff
*/
public class ResultModel {
private String errorCode;
private String message;
private Object data;
public ResultModel() {
}
public ResultModel(String errorCode, String message) {
this.errorCode = errorCode;
this.message = message;
}
public ResultModel(String errorCode, String message, Object data) {
this.errorCode = errorCode;
this.message = message;
this.data = data;
}
public String getErrorCode() {
return errorCode;
}
public void set ErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static ResultModel ok(String testValue) {
ResultModel rm = new ResultModel();
rm.setData(testValue);
return rm;
}
}
品茗IT-博客专题:https://www.pomit.cn/lecture.html汇总了Spring专题、Springboot专题、SpringCloud专题、web基础配置专题。
快速构建项目
Spring项目快速开发工具:
一键快速构建Spring项目工具
一键快速构建SpringBoot项目工具
一键快速构建SpringCloud项目工具
一站式Springboot项目生成
Mysql一键生成Mybatis注解Mapper
Spring组件化构建
SpringBoot组件化构建
SpringCloud服务化构建
喜欢这篇文章么,喜欢就加入我们一起讨论SpringCloud使用吧!