当前位置: 首页 > news >正文

网站的制作公司网络营销师工作内容

网站的制作公司,网络营销师工作内容,window7用jsp做的网站要什么工具,网站内链规划文章目录 一、介绍二、auth微服务代码1. SecurityConfig2. UserDetailsService3. 总结 三、gateway微服务代码1. 统一处理CORS问题 四、content微服务代码1. controller2. SecurityConfig3. 解析JWT Utils4. 总结 五、一些坑 书接上文 微服务OAuth 2.1认证授权可行性方案(Sprin… 文章目录 一、介绍二、auth微服务代码1. SecurityConfig2. UserDetailsService3. 总结 三、gateway微服务代码1. 统一处理CORS问题 四、content微服务代码1. controller2. SecurityConfig3. 解析JWT Utils4. 总结 五、一些坑 书接上文 微服务OAuth 2.1认证授权可行性方案(Spring Security 6) 一、介绍 三个微服务 auth微服务作为认证服务器用于颁发JWT。gateway微服务作为网关用于拦截过滤。content微服务作为资源服务器用于校验授权。 以下是授权相关数据库。 user表示用户表role表示角色表user_role关联了用户和角色表示某个用户是是什么角色。一个用户可以有多个角色menu表示资源权限表。PreAuthorize(hasAuthority(xxx))时用的就是这里的code。permission关联了角色和资源权限表示某个角色用于哪些资源访问权限一个角色有多个资源访问权限。 当我们知道userId我们就可以知道这个用户可以访问哪些资源并把这些权限也就是menu里的code字段写成数组写到JWT的负载部分的authorities字段中。当用户携带此JWT访问具有PreAuthorize(hasAuthority(xxx))修饰的资源时我们解析出JWT中的authorities字段判断是否包含hasAuthority指定的xxx权限以此来完成所谓的的“授权”。 二、auth微服务代码 1. SecurityConfig package com.xuecheng.auth.config;import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.MediaType; import org.springframework.security.config.Customizer; 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.configurers.AbstractHttpConfigurer; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.time.Duration; import java.util.List; import java.util.UUID; import java.util.stream.Collectors;/*** 身份验证服务器安全配置** author mumu* date 2024/02/13*/ //EnableGlobalMethodSecurity(securedEnabled true, prePostEnabled true) Configuration EnableWebSecurity public class AuthServerSecurityConfig {private static KeyPair generateRsaKey() {KeyPair keyPair;try {KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance(RSA);keyPairGenerator.initialize(2048);keyPair keyPairGenerator.generateKeyPair();} catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}/*** 密码编码器* 用于加密认证服务器client密码和用户密码** return {link PasswordEncoder}*/Beanpublic PasswordEncoder passwordEncoder() {// 密码为明文方式// return NoOpPasswordEncoder.getInstance();// 或使用 BCryptPasswordEncoderreturn new BCryptPasswordEncoder();}/*** 授权服务器安全筛选器链* br/* 来自Spring Authorization Server示例用于暴露Oauth2.1端点一般不影响常规的请求** param http http* return {link SecurityFilterChain}* throws Exception 例外*/BeanOrder(1)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0http// Redirect to the login page when not authenticated from the// authorization endpoint.exceptionHandling((exceptions) - exceptions.defaultAuthenticationEntryPointFor(new LoginUrlAuthenticationEntryPoint(/login),new MediaTypeRequestMatcher(MediaType.TEXT_HTML)))// Accept access tokens for User Info and/or Client Registration.oauth2ResourceServer((resourceServer) - resourceServer.jwt(Customizer.withDefaults()));return http.build();}/*** 默认筛选器链* br/* 这个才是我们需要关心的过滤链可以指定哪些请求被放行哪些请求需要JWT验证** param http http* return {link SecurityFilterChain}* throws Exception 例外*/BeanOrder(2)public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -authorize.requestMatchers(new AntPathRequestMatcher(/actuator/**)).permitAll().requestMatchers(new AntPathRequestMatcher(/login)).permitAll().requestMatchers(new AntPathRequestMatcher(/logout)).permitAll().requestMatchers(new AntPathRequestMatcher(/wxLogin)).permitAll().requestMatchers(new AntPathRequestMatcher(/register)).permitAll().requestMatchers(new AntPathRequestMatcher(/oauth2/**)).permitAll().requestMatchers(new AntPathRequestMatcher(/**/*.html)).permitAll().requestMatchers(new AntPathRequestMatcher(/**/*.json)).permitAll().requestMatchers(new AntPathRequestMatcher(/auth/**)).permitAll().anyRequest().authenticated()).csrf(AbstractHttpConfigurer::disable)//指定logout端点用于退出登陆不然二次获取授权码时会自动登陆导致短时间内无法切换用户.logout(logout - logout.logoutUrl(/logout).addLogoutHandler(new SecurityContextLogoutHandler()).logoutSuccessUrl(http://www.51xuecheng.cn)).formLogin(Customizer.withDefaults()).oauth2ResourceServer(oauth2 - oauth2.jwt(Customizer.withDefaults()) // .jwt(jwt - jwt // .jwtAuthenticationConverter(jwtAuthenticationConverter()) // ));return http.build();}private JwtAuthenticationConverter jwtAuthenticationConverter() {JwtAuthenticationConverter jwtConverter new JwtAuthenticationConverter();return jwtConverter;}/*** 客户端管理实例* br/* 来自Spring Authorization Server示例** return {link RegisteredClientRepository}*/Beanpublic RegisteredClientRepository registeredClientRepository() {RegisteredClient registeredClient RegisteredClient.withId(UUID.randomUUID().toString()).clientId(XcWebApp).clientSecret(passwordEncoder().encode(XcWebApp)).clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).redirectUri(http://www.51xuecheng.cn).redirectUri(http://localhost:63070/auth/wxLogin).redirectUri(http://www.51xuecheng.cn/sign.html) // .postLogoutRedirectUri(http://localhost:63070/login?logout).scope(all).scope(OidcScopes.OPENID).scope(OidcScopes.PROFILE).scope(message.read).scope(message.write).scope(read).scope(write).clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).tokenSettings(TokenSettings.builder().accessTokenTimeToLive(Duration.ofHours(2)) // 设置访问令牌的有效期.refreshTokenTimeToLive(Duration.ofDays(3)) // 设置刷新令牌的有效期.reuseRefreshTokens(true) // 是否重用刷新令牌.build()).build();return new InMemoryRegisteredClientRepository(registeredClient);}/*** jwk源* br/* 对访问令牌进行签名的示例里面包含公私钥信息。** return {link JWKSource}{link SecurityContext}*/Beanpublic JWKSourceSecurityContext jwkSource() {KeyPair keyPair generateRsaKey();RSAPublicKey publicKey (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey (RSAPrivateKey) keyPair.getPrivate();RSAKey rsaKey new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();JWKSet jwkSet new JWKSet(rsaKey);return new ImmutableJWKSet(jwkSet);}/*** jwt解码器* br/* JWT解码器主要就是基于公钥信息来解码** param jwkSource jwk源* return {link JwtDecoder}*/Beanpublic JwtDecoder jwtDecoder(JWKSourceSecurityContext jwkSource) {return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);}Beanpublic AuthorizationServerSettings authorizationServerSettings() {return AuthorizationServerSettings.builder().build();}/*** JWT定制器* BR/* 可以往JWT从加入额外信息这里是加入authorities字段是一个权限数组。** return {link OAuth2TokenCustomizer}{link JwtEncodingContext}*/Beanpublic OAuth2TokenCustomizerJwtEncodingContext jwtTokenCustomizer() {return context - {Authentication authentication context.getPrincipal();if (authentication.getPrincipal() instanceof UserDetails userDetails) {ListString authorities userDetails.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());context.getClaims().claim(authorities, authorities);}};} }这里需要注意几点 使用BCryptPasswordEncoder密码加密在设置clientSecret时需要手动使用密码编码器。jwtTokenCustomizer解析UserDetails然后往JWT中添加authorities字段为了后面的授权。 2. UserDetailsService package com.xuecheng.ucenter.service.impl;import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xuecheng.ucenter.mapper.XcMenuMapper; import com.xuecheng.ucenter.mapper.XcUserMapper; import com.xuecheng.ucenter.model.dto.AuthParamsDto; import com.xuecheng.ucenter.model.dto.XcUserExt; import com.xuecheng.ucenter.model.po.XcMenu; import com.xuecheng.ucenter.model.po.XcUser; import com.xuecheng.ucenter.service.AuthService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component;import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;Component Slf4j public class UserServiceImpl implements UserDetailsService {Autowiredprivate MyAuthService myAuthService;AutowiredXcMenuMapper xcMenuMapper;/*** 用户统一认证** param s 用户信息Json字符串* return {link UserDetails}* throws UsernameNotFoundException 找不到用户名异常*/Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {XcUserExt xcUserExt myAuthService.execute(username);return getUserPrincipal(xcUserExt);}public UserDetails getUserPrincipal(XcUserExt user){//用户权限,如果不加报Cannot pass a null GrantedAuthority collectionListXcMenu xcMenus xcMenuMapper.selectPermissionByUserId(user.getId());String[] permissions {read};if (ObjectUtils.isNotEmpty(xcMenus)){permissions xcMenus.stream().map(XcMenu::getCode).toList().toArray(String[]::new);log.info(权限如下:{}, Arrays.toString(permissions));}//为了安全在令牌中不放密码String password user.getPassword();user.setPassword(null);//将user对象转jsonString userString JSON.toJSONString(user);//创建UserDetails对象return User.withUsername(userString).password(password).authorities(permissions).build();} } 这里需要注意几点 username就是前端/auth/login的时候输入的账户名。myAuthService.execute(username)不抛异常就默认表示账户存在此时将password加入UserDetails 并返回Spring Authorization Server对比校验两个密码。myAuthService.execute(username)根据username获取用户信息返回将用户信息存入withUsername中Spring Authorization Server默认会将其加入到JWT中。现在Spring Authorization Server默认不会把authorities(permissions)写入JWT需要配合OAuth2TokenCustomizer手动写入。 3. 总结 这样auth微服务颁发的JWT现在就会包含authorities字段。示例如下 {active: true,sub: {\cellphone\:\17266666637\,\createTime\:\2024-02-13 10:33:13\,\email\:\1138882663qq.com\,\id\:\012f3a90-2bc9-4a2c-82a3-f9777c9ac10a\,\name\:\xiamu\,\nickname\:\xiamu\,\permissions\:[],\status\:\1\,\updateTime\:\2024-02-13 10:33:13\,\username\:\xiamu\,\utype\:\101001\,\wxUnionid\:\test\},aud: [XcWebApp],nbf: 1707830437,scope: all,iss: http://localhost:63070/auth,exp: 1707837637,iat: 1707830437,jti: 8a657c60-968f-4d98-8a4c-22a7b4ecd333,authorities: [xc_sysmanager,xc_sysmanager_company,xc_sysmanager_doc,xc_sysmanager_log,xc_teachmanager_course_list],client_id: XcWebApp,token_type: Bearer }三、gateway微服务代码 1. 统一处理CORS问题 EnableWebFluxSecurity Configuration public class SecurityConfig {//安全拦截配置Beanpublic SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception {return http.cors(cors - cors.configurationSource(corsConfigurationSource())).authorizeExchange(exchanges -exchanges.pathMatchers(/**).permitAll().anyExchange().authenticated()).oauth2ResourceServer(oauth2 - oauth2.jwt(Customizer.withDefaults())).csrf(ServerHttpSecurity.CsrfSpec::disable).build();}Beanpublic CorsConfigurationSource corsConfigurationSource() {CorsConfiguration corsConfig new CorsConfiguration();corsConfig.addAllowedOriginPattern(*); // 允许任何源corsConfig.addAllowedMethod(*); // 允许任何HTTP方法corsConfig.addAllowedHeader(*); // 允许任何HTTP头corsConfig.setAllowCredentials(true); // 允许证书cookiescorsConfig.setMaxAge(3600L); // 预检请求的缓存时间秒UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**, corsConfig); // 对所有路径应用这个配置return source;} } 这里需要注意几点 书接上文这里虽然用了oauth2.jwt(Customizer.withDefaults())但实际上基于远程auth微服务开放的jwkSetEndpoint配置的JwtDecoder。.cors(cors - cors.configurationSource(corsConfigurationSource()))一次性处理CORS问题。 四、content微服务代码 1. controller PreAuthorize(hasAuthority(xc_teachmanager_course_list))ApiResponse(responseCode 200, description Successfully retrieved user)Operation(summary 查询课程信息列表)PostMapping(/course/list)public PageResultCourseBase list(PageParams pageParams,Parameter(description 请求具体内容) RequestBody(required false) QueryCourseParamsDto dto){SecurityUtil.XcUser xcUser SecurityUtil.getUser();if (xcUser ! null){System.out.println(xcUser.getUsername());System.out.println(xcUser.toString());}return courseBaseInfoService.queryCourseBaseList(pageParams, dto);}使用了PreAuthorize(hasAuthority(xc_teachmanager_course_list))修饰的controller资源。 2. SecurityConfig Configuration EnableWebSecurity EnableMethodSecurity public class SecurityConfig {//安全拦截配置Beanpublic SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorize) -authorize.requestMatchers(/**).permitAll().anyRequest().authenticated()).csrf(AbstractHttpConfigurer::disable).oauth2ResourceServer(oauth - oauth.jwt(jwt - jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())));return http.build();}private JwtAuthenticationConverter jwtAuthenticationConverter() {JwtAuthenticationConverter jwtConverter new JwtAuthenticationConverter();jwtConverter.setJwtGrantedAuthoritiesConverter(jwt - {// 从JWT的claims中提取权限信息ListString authorities jwt.getClaimAsStringList(authorities);if (authorities null) {return Collections.emptyList();}return authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());});return jwtConverter;} }需要注意几点 使用EnableMethodSecurity让PreAuthorize生效和gateway一样需要基于远程auth微服务开放的jwkSetEndpoint配置JwtDecoder。指定JwtAuthenticationConverter 让anyRequest().authenticated()需要验证的请求除了完成默认的JWT验证外还需要完成JwtAuthenticationConverter 指定逻辑。JwtAuthenticationConverter 中将JWT的authorities部分形成数组后写入GrantedAuthorities这正是spring security6用于校验PreAuthorize的字段。 3. 解析JWT Utils Slf4j public class SecurityUtil {public static XcUser getUser(){Authentication authentication SecurityContextHolder.getContext().getAuthentication();if (authentication null){return null;}if (authentication instanceof JwtAuthenticationToken) {JwtAuthenticationToken jwtAuth (JwtAuthenticationToken) authentication;System.out.println(jwtAuth);MapString, Object tokenAttributes jwtAuth.getTokenAttributes();System.out.println(tokenAttributes);Object sub tokenAttributes.get(sub);return JSON.parseObject(sub.toString(), XcUser.class);}return null;}Datapublic static class XcUser implements Serializable {private static final long serialVersionUID 1L;private String id;private String username;private String password;private String salt;private String name;private String nickname;private String wxUnionid;private String companyId;/*** 头像*/private String userpic;private String utype;private LocalDateTime birthday;private String sex;private String email;private String cellphone;private String qq;/*** 用户状态*/private String status;private LocalDateTime createTime;private LocalDateTime updateTime;} }把JWT的信息解析回XcUser 相当于用户携带JWT访问后端后端可以根据JWT获取此用户的信息。当然你可以尽情的自定义扩展。 4. 总结 当用户携带JWT访问需要权限的资源时现在可以正常的校验权限了。 五、一些坑 写RegisteredClient时注册那么多redirectUri是因为debug了很久才发现获取授权码和获取JWT时redirect_uri参数需要一致。cors问题spring secuity6似乎会一开始直接默认拒绝cors导致跨域请求刚到gateway就寄了到不了content微服务即使content微服务配置了CORS的处理方案也无济于事。
http://www.dnsts.com.cn/news/157218.html

相关文章:

  • 网站建设代码标签大全成全视频免费观看在线看第6季动漫版
  • 零基础怎么做网站百度用户服务中心人工电话
  • 如何制作产品网站模板下载地址如何接单做网站
  • 网站换服务器要怎么做低代码无代码平台
  • 济宁市做网站的公司wordpress t1主题
  • 南城免费做网站wordpress作者信息
  • 建设银行甘肃分行网站怎么做网站建设赚钱
  • 网站开发毕业设计摘要范文镇江网站优化哪家好
  • 微网站如何建设方案廊坊网站建设墨子
  • 论企业网站建设的好处的文献郑州专业网站推广公司
  • 专门做推广的网站中国域名查询
  • 辽宁省建设厅科技中心网站wordpress美化文章标题
  • 做app网站公司名称官方网站改版建议
  • wordpress全站启用ssl外贸网站打开速度
  • 购物网站开发背景需求重庆营销型网站建设
  • 网站建设代管推广android系统开发
  • 网站服务器空间价格个人网站名称怎么取容易备案
  • wordpress建立好的网站长沙外贸网站
  • 成都网站建设推广详情建设银行公积金预约网站
  • 重庆勘察设计协会网站wordpress评论表情包
  • 从用户角度网站应该具备的条件网站开发的结构图
  • 怎么自己网站建设商业网站网页
  • 代做论文网站好亦庄网站开发
  • win7 iis建立网站石家庄网站建设规划
  • 集团网站建dede手机网站跳转
  • 网站建设 软件有哪些方面wordpress主题demo
  • 行业 网站 方案制作个网站需要多少钱
  • 网站wordpress安徽省博物馆网站建设
  • 长沙做产检玛丽亚m网站wordpress 源码出售
  • 辽宁省网站备案系统wap盛唐建站