本次实例涉及三个项目 核心项目工程unify_authorization_server(认证授权登录) 资源服务器项目unify_resource_server 测试项目是前面几篇写的项目 这里没有改
本次实例涉及三个项目
核心项目工程unify_authorization_server(认证授权登录)
资源服务器项目unify_resource_server
测试项目是前面几篇写的项目 这里没有改动直接用来测试实例项目
pom相关依赖 我采用的是spring-boot 2.6.3
4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.3 com.xql unify_authorization_server 0.0.1-SNAPSHOT war unify_authorization_server unify_authorization_server 8 8 UTF-8 2.6.3 1.8 8.0.28 1.2.83 2.1.2.RELEASE 3.1.0 2021.0.4 1.0.10.RELEASE 1.18.8 5.8.16 2.2.2 2.9.2 1.5.24 1.9.3 1.5.24 org.springframework.boot spring-boot-dependencies ${spring-boot-version} pom import org.springframework.cloud spring-cloud-dependencies ${spring-cloud-version} pom import javax.servlet javax.servlet-api ${servlet.version} Mysql mysql-connector-java ${mysql.version} com.alibaba fastJSON ${fastjson.version} org.springframework.security spring-security-Jwt ${security-jwt.version} org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure ${oauth2.version} org.springframework.cloud spring-cloud-starter-security ${oauth2.version} org.springframework.cloud spring-cloud-starter-oauth2 ${oauth2.version} org.springframework.boot spring-boot-starter-WEB org.aspectj aspectjrt 1.8.6 org.aspectj aspectjweaver 1.8.6 com.Google.code.gson gson 2.10.1 org.springframework.boot spring-boot-starter-data-Redis org.springframework.cloud spring-cloud-starter-security org.springframework.cloud spring-cloud-starter-oauth2 org.springframework.security spring-security-jwt javax.interceptor javax.interceptor-api 1.2 com.alibaba fastjson mysql mysql-connector-java org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 org.projectlombok lombok ${lombok.version} cn.hutool hutool-all ${hutool.version} org.springframework.security spring-security-jwt io.jsonwebtoken jjwt 0.9.0 org.apache.Tomcat.embed tomcat-embed-jasper 9.0.69 jstl jstl 1.2 javax.servlet javax.servlet-api 4.0.1 io.springfox springfox-swagger2 ${swagger2.version} swagger-annotations io.swagger io.springfox springfox-swagger-ui ${swagger2.version} io.swagger swagger-annotations ${swagger2.annotations.version} io.swagger swagger-models ${swagger2.models.version} com.GitHub.xiaoymin swagger-bootstrap-ui ${swagger2.bootstrapui.version} javax.validation validation-api 2.0.1.Final unify_authorization_server ${basedir}/src/main/webapp META-INF/resources **** org.springframework.boot spring-boot-Maven-plugin 1.4.2.RELEASE true com.xql.unify_authorization_server.UnifyAuthorizationServerApplication
application.properties
spring.application.name=uaa-serviceserver.port=53020spring.main.allow-bean-definition-overriding=trueserver.servlet.context-path=/uaa-servicespring.mvc.throw-exception-if-no-handler-found=truespring.web.resources.add-mappings=falsemanagement.endpoints.web.exposure.include=refresh,health,info,env#mysql???spring.datasource.river-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url= jdbc:mysql://xxxxxxxxxxxx:3307/oauth?useUnicode=true&characterEncoding=utf8spring.datasource.username= rootspring.datasource.passWord= xxxxxx# ?????????????????????????????????''spring.main.allow-circular-references=truespring.redis.host=xxxxxxxxxxxxspring.redis.port=6379spring.redis.password=xxxxxxxxxxxmybatis.type-aliases-package= com.xql.unify_authorization_server.entitymybatis.mapper-locations= classpath:mapper@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Autowired JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;// @Autowired// private AuthenticationEntryPoint authenticationEntryPoint; @Autowired private AccessDeniedHandler accessDeniedHandler; @Bean public httpsessionRequestCache HttpSessionRequestCache() { return new HttpSessionRequestCache(); } protected void configure(HttpSecurity http) throws Exception { http //关闭csrf .csrf().disable() //不通过Session获取SecurityContext .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() // 对于登录接口 允许匿名访问 .antMatchers("/login/oauth", "/login/in", "/imagespublic class MyAuthenticationProvider implements AuthenticationProvider { @Autowired private UserDetailsService userDetailsService; @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { Optional optional = Optional.ofNullable(authentication); String userAccount = optional.map(Authentication::getPrincipal) .map(String::valueOf) .orElse(""); if (StrUtil.isNotBlank(userAccount)){ UserDetails details = userDetailsService.loadUserByUsername(userAccount); LoginUser loginUser = Optional.ofNullable(details) .map(key -> (LoginUser) key) .orElse(null); Collection extends GrantedAuthority> authorities = Optional.ofNullable(loginUser) .map(LoginUser::getAuthorities) .orElse(null); return new UsernamePasswordAuthenticationToken(loginUser, authentication.getCredentials(), authorities); } return null; } @Override public boolean supports(Class> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); }}
package com.xql.unify_authorization_server.config;import cn.hutool.core.util.StrUtil;import com.xql.unify_authorization_server.commons.SystemConstant;import com.xql.unify_authorization_server.entity.LoginUser;import com.xql.unify_authorization_server.enums.RedisEnums;import com.xql.unify_authorization_server.utils.JwtUtil;import io.jsonwebtoken.Claims;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.stereotype.Component;import org.springframework.util.AntPathMatcher;import org.springframework.util.Assert;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Objects;import java.util.Optional;@Componentpublic class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Autowired private RedisCache redisCache; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 获取请求路径 String requestURI = request.getRequestURI(); // 判断是否是登录请求 AntPathMatcher pathMatcher = new AntPathMatcher(); if (pathMatcher.match(SystemConstant.Jwt.NO_JWT_TOKEN_MATCHER_ONE, requestURI)) { filterChain.doFilter(request, response); return; } String authorization = request.getHeader(SystemConstant.Jwt.Authorization); if (pathMatcher.match(SystemConstant.Jwt.NO_JWT_TOKEN_MATCHER_TWO, requestURI)) { authorization = Optional.ofNullable(redisCache.getCacheObject(request.getParameter(SystemConstant.Jwt.STATE))).map(String::valueOf).orElse(""); } if (StrUtil.isBlank(authorization)) { filterChain.doFilter(request, response); return; } authorization = Optional.ofNullable(authorization) .map(token->token.replace(SystemConstant.Jwt.BEARER, "")) .orElse(""); //解析token String userId; try { Claims claims = JwtUtil.parseJWT(authorization); userId = claims.getSubject(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(authorization+"非法authorization"); } //从redis中获取用户信息 LoginUser user = redisCache.getCacheObject(RedisEnums.login(userId)); request.setAttribute(SystemConstant.Jwt.USER_BEAN, user); request.setAttribute(SystemConstant.Jwt.AUTHORIZATION_TOKEN, authorization); Assert.isTrue(Objects.nonNull(user),"用户未登录"); //存入SecurityContextHolder //TODO 获取权限信息封装到Authentication中 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authenticationToken); //放行 filterChain.doFilter(request, response); }}
package com.xql.unify_authorization_server.config;import com.xql.unify_authorization_server.commons.SystemConstant;import com.xql.unify_authorization_server.service.impl.MyAuthorizationCodeServices;import com.xql.unify_authorization_server.service.impl.MyClientDetailsService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.security.authentication.AuthenticationManager;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.configurers.AuthorizationServerEndpointsConfigurer;import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;@Configurationpublic class AuthorizationConfig extends AuthorizationServerConfigurerAdapter { @Autowired AuthenticationManager authenticationManager; @Autowired private AuthorizationServerTokenServices authorizationServerTokenServices; @Autowired private MyClientDetailsService clientDetailsService; @Autowired private MyAuthorizationCodeServices authorizationCodeServices; @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { //tokenKeyAccess oauth/token_key公开 //checkTokenAccess oauth/check_token公开 security .tokenKeyAccess(SystemConstant.Oauth.PERMIT_ALL) .checkTokenAccess(SystemConstant.Oauth.PERMIT_ALL) .allowFORMAuthenticationForClients(); // 表单认证,申请令牌 } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(clientDetailsService); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .authorizationCodeServices(authorizationCodeServices) .authenticationManager(authenticationManager) .tokenServices(authorizationServerTokenServices) .pathMapping(SystemConstant.Oauth.CONFIRM_ACCESS,SystemConstant.Oauth.MY_CONFIRM_ACCESS); }}
其中这个配置是去自定义数据库查询客户端信息
这个地方可以替换映射的路径 ,这里我们替换了自定义授权页面接口从原来默认的/oauth/confirm_access变成了我们自己的/custom/confirm_access
package com.xql.unify_authorization_server.config;import com.xql.unify_authorization_server.service.impl.MyAccessToken;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.oauth2.provider.token.TokenStore;import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;@Configurationpublic class AccessTokenConfig { @Value("${jwt.signing.key}") private String SIGNING_KEY; @Bean TokenStore tokenStore() { return new JwtTokenStore(jwtAccessTokenConverter()); } @Bean JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter converter = new MyAccessToken(); converter.setSigningKey(SIGNING_KEY); return converter; }}
package com.xql.unify_authorization_server.bean;import com.xql.unify_authorization_server.config.CustomAdditionalInformation;import com.xql.unify_authorization_server.service.impl.MyClientDetailsService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;import org.springframework.security.oauth2.provider.token.DefaultTokenServices;import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;import org.springframework.security.oauth2.provider.token.TokenStore;import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;import java.util.Arrays;@Configurationpublic class AuthorizationBean { @Autowired private TokenStore tokenStore; @Autowired private MyClientDetailsService clientDetailsService; @Autowired JwtAccessTokenConverter jwtAccessTokenConverter; @Autowired CustomAdditionalInformation customAdditionalInformation; @Bean public AuthorizationServerTokenServices authorizationServerTokenServices() { DefaultTokenServices services = new DefaultTokenServices(); //客户端详情服务 services.setClientDetailsService(clientDetailsService); //允许令牌自动刷新 services.setSupportRefreshToken(true); //令牌存储策略-JWT services.setTokenStore(tokenStore); TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter, customAdditionalInformation)); services.setTokenEnhancer(tokenEnhancerChain); return services; }}
配置完成上面信息我们来书写自定义登录页面
我们在controller写一个去登录页面的接口 这里从HttpSessionRequestCache获取本次请求的客户端拦截路径跳转到login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> xql 来源地址:https://blog.csdn.net/qq_42264638/article/details/131289529
--结束END--
本文标题: Spring Security OAuth2.0(五)-----OAuth2实现自定义统一认证登录页/自定义授权页/基于mysql存储数据
本文链接: https://www.lsjlt.com/news/402784.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-09
2024-05-09
2024-05-09
2024-05-09
2024-05-09
2024-05-08
2024-05-08
2024-05-08
2024-05-08
2024-05-08
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0