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

做门户网站价格网站怎么盈利的

做门户网站价格,网站怎么盈利的,河北邯郸特产,有哪些可以做翻译兼职的网站吗SpringSecurity 集成第三方登录 认证及自定义流程 首先我们提供一个实现了AbstractAuthenticationProcessingFilter抽象类的过滤器#xff0c;用来代替UsernamePasswordAuthenticationFilter逻辑#xff0c;然后提供一个AuthenticationProvider实现类代替AbstractUserDetail…SpringSecurity 集成第三方登录 认证及自定义流程 首先我们提供一个实现了AbstractAuthenticationProcessingFilter抽象类的过滤器用来代替UsernamePasswordAuthenticationFilter逻辑然后提供一个AuthenticationProvider实现类代替AbstractUserDetailsAuthenticationProvider或DaoAuthenticationProvider最后再提供一个UserDetailsService实现类。 1.验证码登录 1.通用过滤器实现–ThirdAuthenticationFilter 这个ThirdAuthenticationFilter过滤器我们可以仿照UsernamePasswordAuthenticationFilter来实现也实现了AbstractAuthenticationProcessingFilter抽象类主要是重新定义了attemptAuthentication()方法这里需要根据“authType”参数值的类别构建不同的AbstractAuthenticationToken具体实现如下 //验证类型比如Sms,uernamepassword等private String authTypeParameter authType;//对应用户名或手机号等private String principalParameter principal;//对应密码或验证码等private String credentialsParameter credentials;private boolean postOnly true;public ThirdAuthenticationFilter() {super(new AntPathRequestMatcher(/login/doLogin, POST));}Overridepublic 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 authType request.getParameter(authTypeParameter);if(StringUtils.isEmpty(authType)){authType AuthTypeEnum.AUTH_TYPE_DEFAULT.getAuthType();}String principal request.getParameter(principalParameter);String credentials request.getParameter(credentialsParameter);AbstractAuthenticationToken authRequest null;switch (authType){case sms:authRequest new SmsAuthenticationToken(principal, credentials);((SmsAuthenticationToken)authRequest).setCode((String)request.getSession().getAttribute(code));break;case github:authRequest new GithubAuthenticationToken(principal, credentials);break;case default:authRequest new UsernamePasswordAuthenticationToken(principal, credentials);}authRequest.setDetails(authenticationDetailsSource.buildDetails(request));return this.getAuthenticationManager().authenticate(authRequest);} }定义了ThirdAuthenticationSecurityConfig 配置类我们还需要在SpringSecurity配置类中应用才能生效具体实现如下 Override protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers(/error,/login/**,/login/goLogin,/login/doLogin,/login/code,/login/authorization_code).anonymous().anyRequest().authenticated().and().formLogin().loginPage(/login/goLogin).loginProcessingUrl(/login/doLogin).failureUrl(/login/error).permitAll().successHandler(new QriverAuthenticationSuccessHandler(/index/toIndex));//这里我们省略了一些配置 ……//应用前面定义的配置http.apply(thirdAuthenticationSecurityConfig); } 至此我们定义的通用第三方过滤器就完成了并且也完成了在SpringSecurity中生效的配置。下面我们就开始分别实现不同类型登录的具体过程。 在ThirdAuthenticationFilter 类的attemptAuthentication()方法中我们通过authType类型然后创建对应的Authentication实现来实现不同方式的登录这里我们主要实现了如下三种方式我们分别梳理一下。 三、默认的登录过程   默认的登录过程即根据用户名密码进行登录需要使用到UsernamePasswordAuthenticationToken当“authType”参数为default时这里就会创建UsernamePasswordAuthenticationToken对象然后后续通过ProviderManager的authenticate()方法最后就会调用AbstractUserDetailsAuthenticationProviderDaoAuthenticationProvider的 authenticate()方法最终又会调用定义的UserDetailsService实现类。这是默认的过程这里就不再重复其中的逻辑除了UserDetailsService实现类需要自己定义其他都是SpringSecurity提供的实现类。 四、短信验证码登录实现   短信验证码登录是最贴近用户名密码登录的一种方式所以我们完全可以仿照用户名密码这种方式实现。我们这里先梳理一下短信验证码登录的业务逻辑首先登录界面输入手机号码然后再点击“获取验证码”按钮获取短信验证码然后输入收到的短信验证码最后点击“登录”按钮进行登录认证。和用户名密码登录相比短信验证码登录多了一个获取验证码的过程其他其实都是一样的我们下面逐步实现短信验证码登录 RestController RequestMapping(/login) public class SmsValidateCodeController {//生成验证码的实例对象Autowiredprivate ValidateCodeGenerator smsCodeGenerator;//调用服务商接口发送短信验证码的实例对象Autowiredprivate DefaultSmsCodeSender defaultSmsCodeSender;RequestMapping(/code)public String createSmsCode(HttpServletRequest request, HttpServletResponse response) throws ServletRequestBindingException {ValidateCode smsCode smsCodeGenerator.generate(new ServletWebRequest(request));String mobile (String)request.getParameter(principal);request.getSession().setAttribute(code,smsCode.getCode());defaultSmsCodeSender.send(mobile, smsCode.getCode());System.out.println(验证码 smsCode.getCode());return 验证码发送成功;} } 在上述方法中我们注入了smsCodeGenerator和defaultSmsCodeSender两个实例对象分别用来生成验证码和发送短信验证码这个可以根据项目的实际情况进行定义和实现这里不再贴出其中的实现。同时在createSmsCode()方法中还有一点需要注意的就是我们发出去的短信验证码需要进行保存方便后续登录时进行验证这个也可以选择很多方法比如说会话、数据库、缓存等我这里为了简单直接存到了session会话中了。 然后我们前面定义ThirdAuthenticationFilter过滤器时根据登录方式不同需要对应的Authentication对象这里我们还需要创建短信验证登录需要的Authentication类这里我们可以仿照UsernamePasswordAuthenticationToken类进行编写实现如下 public class SmsAuthenticationToken extends AbstractAuthenticationToken {//对应手机号码private final Object principal;//对应手机验证码private Object credentials;//后台存储的短信验证码用于验证前端传过来的是否正确private String code;public SmsAuthenticationToken(String mobile, Object credentials){super(null);this.principal mobile;this.credentials credentials;this.code code;setAuthenticated(false);}public SmsAuthenticationToken(Object principal, Collection? extends GrantedAuthority authorities, Object credentials){super(authorities);this.principal principal;this.credentials credentials;super.setAuthenticated(true);}Overridepublic Object getCredentials() {return this.credentials;}Overridepublic Object getPrincipal() {return this.principal;}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);}public String getCode() {return code;}public void setCode(String code) {this.code code;}Overridepublic void eraseCredentials() {super.eraseCredentials();credentials null;} }在SmsAuthenticationToken 类中我们增加了一个code属性其实该属性不是必须的我这里是为了方便传递存储在session会话中的验证码而添加的如果使用缓存或数据库进行存储验证码该属性就可以省略。 在AuthenticationManager的authenticate()方法中会根据Authentication类型选择AuthenticationProvider对象所以我们这里自定义短信验证码需要的AuthenticationProvider对象实现如下 Component public class SmsAuthenticationProvider implements AuthenticationProvider{AutowiredQualifier(smsUserDetailsService)private UserDetailsService userDetailsService;Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {SmsAuthenticationToken token (SmsAuthenticationToken) authentication;String mobile (String)token.getPrincipal();//首先验证验证码是否正确String code (String)token.getCredentials();String sCode token.getCode();if(StringUtils.isEmpty(code) || !code.equalsIgnoreCase(sCode)){throw new BadCredentialsException(手机验证码错误(Bad credentials)请重试);}//然后查询对应用户UserDetails user userDetailsService.loadUserByUsername(mobile);if (Objects.isNull(user)) {throw new InternalAuthenticationServiceException(根据手机号 mobile 无法获取对应的用户信息);}SmsAuthenticationToken authenticationResult new SmsAuthenticationToken(user.getUsername(), user.getAuthorities(), token.getCredentials());authenticationResult.setDetails(token.getDetails());return authenticationResult;}Overridepublic boolean supports(Class? authentication) {return SmsAuthenticationToken.class.isAssignableFrom(authentication);} } 在SmsAuthenticationProvider 中supports()方法决定了该实例对象仅支持SmsAuthenticationToken对象的验证。同时根据authenticate()方法传递参数authentication对象包括了登录信息手机号和验证码session存储的验证码我们这里session存储的验证码是因为我们采用了会话存储的方式如果使用数据库我们这里就可以通过手机号去数据库或缓存查询对应的验证码然后和authentication对象传递过来的验证码进行比对验证成功说明登录认证成功否则登录认证失败。登录成功后我们就可以调用userDetailsService对象的loadUserByUsername()方法获取登录用户的其他相关信息权限等具体实现在自定义的SmsUserDetailsService类中实现具体如下 Component(smsUserDetailsService) public class SmsUserDetailsService implements UserDetailsService {private Logger logger LoggerFactory.getLogger(SmsUserDetailsService.class);Autowiredprivate SysUserService sysUserService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//1、查询用户信息SysUser user new SysUser();user.setMobile(username);SysUser qUser sysUserService.getOne(new QueryWrapper(user),true);if(qUser null) {logger.info(手机号为” username “的用户不存在);throw new UsernameNotFoundException(手机号为” username “的用户不存在);}//2、封装用户角色UserRole userRole sysUserService.getRoleByUserId(qUser.getId());CollectionGrantedAuthority authorities new ArrayList();authorities.add(new SimpleGrantedAuthority(String.valueOf(userRole.getRoleId())));return new LoginUser(qUser.getUsername(), qUser.getPassword(),authorities);} } 2.GitHub登录 和短信验证码登录认证相比Github登录又会有自己的特殊性我们这里先梳理一下基于Github进行登录验证的大致逻辑首先点击Github登录认证按钮然后会跳转到github登录界面输入github系统的用户名密码登录成功就会跳转到我们自己的系统中的首页。和基于用户名密码的登录方式相比Github登录不需要类似用户名和密码这样的输入在自己的系统中同时又需要根据获取到的github用户信息换取在自己系统对应的用户信息。具体实现步骤如下 在github的配置省略 Controller RequestMapping(/login) public class GithubValidateController {Autowiredprivate GithubClientService githubClientService;RequestMapping(/authorization_code)public void authorization_code(HttpServletRequest request, HttpServletResponse response, String code) throws ServletRequestBindingException, IOException {//github登录验证并获取access_tokenMapString,String resp githubClientService.queryAccessToken(code);//跳转本系统的登录流程获取用户信息实现两个系统用户的对接String url http://localhost:8888/qriver-admin/login/doLogin;this.sendByPost(response, url,resp.get(access_token),github);//this.sendByPost(response, url,access_token,github);}public void sendByPost(HttpServletResponse response,String url, String principal, String authType) throws IOException {response.setContentType(text/html);PrintWriter out response.getWriter();out.println(!DOCTYPE HTML PUBLIC \-//W3C//DTD HTML 4.01 Transitional//EN\);out.println(HTML);out.println( HEADTITLEPost 方法/TITLE/HEAD);out.println( BODY);out.println(form name\submitForm\ action\ url \ method\post\);out.println(input type\hidden\ name\principal\ value\ principal \/);out.println(input type\hidden\ name\authType\ value\ authType \/);out.println(/from);out.println(scriptwindow.document.submitForm.submit();/script );out.println( /BODY);out.println(/HTML);out.flush();out.close();}} “/login/authorization_code”接口对应了我们在Github中配置的回调函数即在Github登录验证成功后就会回调该接口我们就是就在回调方法中模拟了用户名密码登录的方式调用了SpringSecurity登录认证需要的“/login/doLogin”接口。这里我们通过queryAccessToken()方法根据回调传递的code获取对应的accessToken然后把accessToken作为登录使用的principal 参数值之而立不需要传递密码因为我们经过Github授权就可以认为完成了登录认证的判断过程了。 其中GithubClientService类提供了获取accessToken和用户信息的两个方法具体实现方式如下 Service public class GithubClientService {//前面在github中配置时产生的private String clientId ######;private String clientSecret ######;private String state 123;private String redirectUri http://localhost:8888/qriver-admin/login/authorization_code;Autowiredprivate RestTemplate restTemplate;Nullableprivate WebApplicationContext webApplicationContext;//获取accessTokenpublic MapString, String queryAccessToken(String code ){MapString, String map new HashMap();map.put(client_id, clientId);map.put(client_secret, clientSecret);map.put(state, state);map.put(code, code);map.put(redirect_uri, redirectUri);MapString,String resp restTemplate.postForObject(https://github.com/login/oauth/access_token, map, Map.class);return resp;}//获取用户信息public MapString, Object queryUser(String accessToken){HttpHeaders httpheaders new HttpHeaders();httpheaders.add(Authorization, token accessToken);HttpEntity? httpEntity new HttpEntity(httpheaders);ResponseEntityMap exchange restTemplate.exchange(https://api.github.com/user, HttpMethod.GET, httpEntity, Map.class);System.out.println(exchange.getBody() exchange.getBody());return exchange null ? null : exchange.getBody();} }其实完成了上述的配置和方式后后续的方式就和短信验证码的逻辑一样了这里我们简要的再梳理一下。 首先我们也需要定义一个基于Github登录需要的Authentication实现类具体实现和前面的SmsAuthenticationToken类似这里不再重复贴代码了。 然后我们再定义一个AuthenticationProvider实现类GithubAuthenticationProvider具体实现如下 Component public class GithubAuthenticationProvider implements AuthenticationProvider{AutowiredQualifier(githubUserDetailsService)private UserDetailsService userDetailsService;Autowiredprivate GithubClientService githubClientService;Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {GithubAuthenticationToken token (GithubAuthenticationToken) authentication;String accessToken (String)token.getPrincipal();//根据accessToken 获取github用户信息MapString, Object userInfo githubClientService.queryUser(accessToken);//然后根据github用户查询对应系统用户信息UserDetails user userDetailsService.loadUserByUsername((String)userInfo.get(login));if (Objects.isNull(user)) {throw new InternalAuthenticationServiceException(根据accessToken accessToken 无法获取对应的用户信息);}GithubAuthenticationToken authenticationResult new GithubAuthenticationToken(user.getUsername(), user.getAuthorities(), token.getCredentials());authenticationResult.setDetails(token.getDetails());return authenticationResult;}Overridepublic boolean supports(Class? authentication) {return GithubAuthenticationToken.class.isAssignableFrom(authentication);} } 在GithubAuthenticationProvider 类的authenticate()方法中参数authentication中对应的是Github授权后传递的accessToken值我们这里需要根据accessToken值换取Github用户信息这里通过queryUser()方法实现然后根据github用户名去获取对应的系统用户信息。如果根据github用户名用户获取的系统用户为空我们可以根据自己的需求自动生成一个用户或者跳转到注册页面让用户注册一个页面这里为了简单我们直接抛出了一个异常。 关于自定义UserDetailsService实现类主要需要实现根据github用户名查询对应系统用户的功能 当认证完成后要返回token可以实现AuthenticationSuccessHandler import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private final JwtTokenProvider jwtTokenProvider; // 假设你有一个JwtTokenProvider类来生成JWT public CustomAuthenticationSuccessHandler(JwtTokenProvider jwtTokenProvider) { this.jwtTokenProvider jwtTokenProvider; } Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { // 生成JWT String token jwtTokenProvider.generateToken(authentication); // 将JWT添加到响应头中 response.setHeader(Authorization, Bearer token); // 或者将JWT添加到响应体中取决于你的API设计 // response.getWriter().write(token); response.setStatus(HttpServletResponse.SC_OK); } }并在securityconfig中设置
http://www.zqtcl.cn/news/691662/

相关文章:

  • 网站建设注意的问题网站模板 知乎
  • 自主设计和创建网站网站建设价格便宜
  • 高手做网站财经资讯网站该怎么做推广
  • 加强农业网站建设青岛全网营销推广
  • 做淘客网站怎么样济南软件公司排名
  • 企业网站优化兴田德润怎么样网站建设建设公司资质要求
  • 如何把网站做跳转浏览器链接地址wordpress 离线更新
  • 乌海学校网站建设wordpress默认主题下载
  • 海兴县做网站如何选网站建设公司
  • asp网站设为首页代码孝仙洪高速公路建设指挥部网站
  • 浦东新区网站开发人才网站建设策划书
  • 网站做flash好不好免费微信公众号素材网
  • 开发网站嵌入广告汕头电商网站建设
  • 电脑做科目一网站购物网站怎么创建
  • c2c网站建设公司wordpress被公众号干掉
  • wordpress托管建站网站页面布局和样式设计
  • 建站平台江苏省建设监理协会网站
  • 安徽网站开发培训价格百度seo排名公司
  • 青海网站建设费用oa系统和erp系统区别
  • 个人做网站的注意事项网站开发工程师6
  • 镇江百度网站建设北京网站开发价格
  • 大岭山镇仿做网站推广计划表格
  • 网站备案地址不是我的地址怎么办建设银行网站查询业务收费吗
  • 电商网站设计内容网站编辑及seo招聘
  • 用什么网站开发浙江省住房和建设厅网站
  • 站长工具seo优化建议微信小程序线上商城怎么申请
  • 建筑网站开发设计做网站的公司msgg
  • 设计师个人网站模板网站的尾页要怎么做
  • 营销型网站建设风格设定包括哪些方面wordpress企业魔板
  • 怎样做淘客网站做绿色产品的网站