商家管理后台(拼多多商家登录入口网页版)

SSO设计Spring Security是一个强大的可定制的认证和访问控制框架。Spring Security OAuth2是基于Spring框架支持第三方应用

SSO设计

Spring Security是一个强大的可定制的认证和访问控制框架。Spring Security OAuth2是基于Spring框架支持第三方应用授权的工具组件。有了Spring Security OAuth2,我们可以在商户后台设计单点登录(SSO),从而整合多个微服务应用,使用统一的安全控制管理。

SSO设计分为两部分:服务器和客户端。SSO服务器为各个应用提供统一的访问控制和认证服务,是一个Web UI微服务应用。它是在模块merchant-sso中开发的,包括用户登录设计、主页设计和认证服务设计。客户端SSO是指为用户提供本地服务的程序。

单点登录的基本配置

SSO的基本配置与Web UI应用项目的一般配置基本相同,即在Web UI应用项目配置的基础上,增加了Spring Cloud OAuth2的依赖引用,代码如下:

& lt依赖性& gt& lt组Id & gtorg . spring framework . cloud & lt;/groupId & gt;& ltartifactId & gtspring-cloud-starter-oauth 2 & lt;/artifact id & gt;& lt/dependency & gt;该组件已经包含两个组件系统:Security和OAuth2,其中Security提供访问控制功能,OAuth2提供第三方应用授权和认证服务。

在应用配置文件application.yml中,设置SSO应用的服务端口,并设置cookie保存用户的登录信息。代码如下:

server:port:8000 session:cookie:name:session id为了保证授权后可以正常访问第三方应用,我们必须在配置文件中添加access SSO客户端的返回地址列表,并使用正确的格式“http:/l域名或IP: port /login”进行设置。代码如下:

# SSO客户端返回的地址列表SSO客户端:重定向uri:-http://localhost:8081/log in-http://127 . 0 . 0 . 1:8081/1登录SSO第三方应用授权设计

为了授权访问SSO的第三方应用程序(这里是访问SSO服务的其他微服务应用程序),我们创建了一个配置类AuthServerConfig,它继承了authorizationserverconfiguureadapter,代码如下:

@ Configuration @ EnableAuthorizationServer @ EnableConfigurationProperties(client URLs . class)公共类authServerConfig扩展authorizationserverconfiguureradaptercautowiredprivate client URLs client URLs;@ override public void configure(AuthorizationServerSecurityConfigurer oauthServer)引发异常{ oauthServer . token key access(& # 34;permit all()& # 34;).checkTokenAccess(& # 34;is authenticated()& # 34;);@ override public void configure(ClientDetailsServiceConfigurer clients)抛出异常{clients.inMemory()。with client(& # 34;ssoclient & # 34).secret(passwordEncoder()。编码(& # 34;ssosecret & # 34)).authorizedGrantTypes(& # 34;授权_代码& # 34;).范围(& # 34;user _ info & # 34).自动批准(true)。redirectUris(client URLs . getredirecturis());@ bean public JwtAccessTokenConverter JwtAccessTokenConverter(){ JwtAccessTokenConverter = new JwtAccessTokenConverter();转换器。setSigningKey(& # 34;德莫西格& # 34;);返回转换器;} aoverridepublic void configure(AuthorizationServerEndpointsConfigurer端点)引发异常{ endpoints . accesstokenconverter(jwtAccessTokenConverter());} @ bean public BCryptPasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder();}}在上面的配置类中,包含了以下主要函数:

(1)使用注释@EnableAuthorizationServer打开SSO服务器的功能。(2)重写第一个配置,打开使用令牌进行授权的功能。

(3)重写第二个configure,为客户端指定表单页面授权方法,即authorization_code,并将用于客户端授权的用户名和密码分别设置为ssoclient和ssosecret。同时导入配置中的客户端回邮地址列表,并将客户端回邮地址列表设置为redirectUris。此外,autoApprove(true)设置为自动确认授权,这省略了客户端必须手动确认授权的步骤。

(4)重写第三个配置,并使用安全的JwtAccessToken。关于这里键的使用,我们简单地使用一个文本演示。如果想使用更安全的方式,可以使用KeyStore来生成用于配置的密钥。

单点登录认证设计

提供如下登录接口,用于接收用户输入的用户名、密码等信息,实现用户登录操作。在登录身份验证中,Spring Security用于验证用户名和密码。

使用以下代码创建一个MyUserDetails类来实现Spring Security的UserDetails:

公共类MyUserDetails实现UserDetails {私有字符串username私有字符串密码;私人收藏& lt?扩展GrantedAuthority & gt当局;私有用户User;public MyUserDetails(字符串用户名,字符串密码,集合& lt?extendsGrantedAuthority & gtauthorities,User User){ this . username = username;this.password =密码;this.authorities =当局;this.user =用户;} ...}以便我们可以导入我们的自定义用户系统,并将其提供给Spring Security进行身份验证。

创建一个MyUserDetailsService类,实现Spring Security的UserDetailsService,提供用户信息,为下一个认证服务导入用户的角色,代码如下:

@componentpublic类MyUserDetailsService实现userdailsservice { @ Autowiredprivate UserService UserService;@ override public User details loaduserbysusername(String username)throwsUsernameNotFoundException { User User = userservice . find byname(username);if(user = = nul 1){ throw new UsernameNotFoundException(& # 34;用户不存在!");}列表& ltSimpleGrantedAuthority & gtauthorities = new ArrayList & lt& gt();列表& lt角色& gtroles = user . get roles();如果(角色!= null){ for(Role Role:roles){ SimpleGrantedAuthority authority = newSimpleGrantedAuthority(Role . getname());authorities . add(authority);} } my user details my user details = new my user details(username,user.getPassword(),authorities,user);返回myUserDetails}}这样Spring Security认证的时候就会调用我们的用户,获取相关的角色,从而完成登录时用户名和密码的验证,为用户配置相应的权限。

为了使上述设计生效,我们还需要创建一个配置类,即security confng“SprngSecurity”的WebSecurityConfigurerAdapter,代码如下:

@ configuration public class security config扩展webSecurityConfigurerAdapter @ autowired private MyUserDetailsService MyUserDetailsService;@ Autowired @ Qualifier(& # 34;数据源& # 34;)私有DataSource dataSource@Bean(name = BeanIds。authentic ation MANAGER)goverridepublicauthenticationmanager AuthenticationManager bean()抛出exception return super . AuthenticationManager bean();@ override protected void configure(AuthenticationManagerBuilder auth)抛出异常{ auth//lre member me . erasecredentials(false)。用户详细信息服务(myUserDetailsService)。passwordEncoder(newcryptpasswordencoder());@ override protected void configure(http security http)抛出exception http . ant matcher(& # 34;/**").authorizeRequests()。蚂蚁匹配器(& # 34;/log in & # 34;)、permitAl1()。蚂蚁匹配器(& # 34;/images/* * & # 34;, "/check code & # 34;, "/scripts/* & # 34;/styles/* * & # 34;).permitAll()。anyRequest()。已验证()。和()。sessionManagement()。sessionCreationPolicy(sessionCreationPolicy。从不)。还有(。exceptionHandling()。accessDeniedPage(& # 34;/deny & # 34;).和()。rememberMe()。tokenValiditySeconds (86400)。token repository(token repository())。和()。formLogin()。log in page(& # 34;/log in & # 34;).permitAll()。success handler(loginsuccessHandler())。和()。注销()。logout URL(& # 34;/logout & # 34;).permitAll()。logoutSuccessUrl(& # 34;/注销& # 34;);} @ bean public JdbcTokenRepositoryImpl token repository()JdbcTokenRepositoryImpl jtr = new JdbcTokenRepositoryImpl()jtr . set data source(data source);返回jtr} @ bean public loginsuccessshandler loginsuccessshandler(){ return new loginsuccessshandler();}}在此配置类中,进行了以下设置:

(1)将用户服务设置为上面定义的MyUserDetailsService。

(2)将登录页面链接指定为/login,这样就可以通过控制器设计来指定视图文件。

(3)指定loginSuccessHandler。

4)忽略图片等静态资源的验证。

(5)指定拒绝访问的错误提示链接/deny。

(6)使用rememberMe()设置来记住用户的登录状态。

(7)指定使用本地数据源存储用户登录状态的临时数据。

对于上面的配置类设计,我们创建一个控制器,设置一个登录链接/登录名,并为其指定一个界面设计页面login.html。代码如下:

@ controller public class log in controller { @ request mapping(& # 34;/1登录& # 34;)公共字符串log in(){ return & # 34;登录& # 34;;)}在界面设计页面login.html中,表单设计主要用于提供登录界面,提供用户名、密码等输入控件。代码如下:

...<form th:action="@{/login}" id="loginForm" method="post"><div class="loginTit png"></div><ul class="infList"><li class="grayBox"><label for="username" class="username-icon"></label><input id="username" class="username" name="username"type="text" placeholder="您的用户名"/><div class="close png hide"></div></li><li class="grayBox"><label class="pwd-icon" id="pwd"></label><input id="password" name="password" class="pwd"type="password" placeholder="登录密码"/><div class="close png hide"></div></li><li class="" id="isCheckCode" style="display: none; "><label class="validateLabel" ></label><input id="checkCode" name=" checkCode" class="checkCotype-"text" placeholder="验证码"/><img onclick="reloadImg ();" style="cursor: pointer"th:src="e{/images/imagecode)" id="validateImg" alt="验证码"class="codePic"title-"验证码。点击此处更新验证码。"/><a class="getother" href="javascript:void(0);"onclick="reloadImg ();" title="点击此处可以更新验证码。">更新</a></li></ul><ul class="infList reloadBtn" style="display: none; "><li><a href="javascript:void(0);" onclick="tologin();">本页面已经失效。请点击此处重新登录。</a></li></u.l><divclass="loginBtnBo×">div class="check-box"><input type="hidden" value="O"id="remember-me" name="remember-me" onclick="if(this.checked) {this.value1}else {this.value=0}"/>span class="toggleCheck no-check" id="repwd"></span>记住我</div><input type="button" id="loginBtn" onclick="verSubmit()value="登录"class="loginBtn png"/></div></form>...

完成设计的登录界面,其显示效果类似于一个浮动窗口,如图10-4所示。...& ltform th:action = & # 34;@ {/log in } & # 34;id = & # 34loginForm & # 34方法= & # 34;邮政& # 34;& gt& ltdiv class = & # 34loginTit png & # 34& gt& lt/div & gt;& ltul class = & # 34英孚& # 34;& gt& lt李class = & # 34灰色盒子& # 34;& gt& lt= & # 34;的标签;用户名& # 34;class = & # 34用户名图标& # 34;& gt& lt/label & gt;& lt输入id = & # 34用户名& # 34;class = & # 34用户名& # 34;name = & # 34用户名& # 34;type = & # 34正文& # 34;placeholder = & # 34您的用户名& # 34;/& gt;& ltdiv class = & # 34关闭png hide & # 34& gt& lt/div & gt;& lt/李& gt& lt李class = & # 34灰色盒子& # 34;& gt& ltlabel class = & # 34密码图标& # 34;id = & # 34pwd & # 34& gt& lt/label & gt;& lt输入id = & # 34密码& # 34;name = & # 34密码& # 34;class = & # 34pwd & # 34type = & # 34密码& # 34;placeholder = & # 34登录密码& # 34;/& gt;& ltdiv class = & # 34关闭png hide & # 34& gt& lt/div & gt;& lt/李& gt& lt李class = & # 34"id = & # 34isCheckCode & # 34style = & # 34显示:无;"& gt& ltlabel class = & # 34有效标签& # 34;& gt& lt/label & gt;& lt输入id = & # 34校验码& # 34;name = & # 34校验码& # 34;class = & # 34支票类型-& # 34;正文& # 34;placeholder = & # 34验证码& # 34;/& gt;& ltimg onclick = & # 34reload img();"style = & # 34光标:指针& # 34;th:src = & # 34;e {/images/image code)& # 34;id = & # 34验证& # 34;alt = & # 34验证码& # 34;class = & # 34codePic & # 34标题-& # 34;验证码。单击此处更新验证码。"/& gt;& lta class = & # 34getother & # 34href = & # 34JavaScript:void(0);"onclick = & # 34reload img();"title = & # 34单击此处更新验证码。"& gt更新

商家管理后台(拼多多商家登录入口网页版)

验证码的描述

用户第一次登录时,看不到验证码。当用户第一次登录失败,需要再次登录时,会要求用户输入验证码。

关于验证码的实现,这里有两种解释,即验证码的输出和验证码的检查。

验证码的输出是一个图像,代码如下:

@ request mapping(value = & # 34;/images/image code & # 34;)公共字符串imagecode (HttpServletRequest请求,HttpServletResponseresponse)抛出异常{ output stream OS = response . get output stream();地图& ltString,0 object & gt;map = ImageCode.getImageCode(60,20,OS);String simpleCaptcha = & # 34简单验证码& # 34;;request.getSession()。setAttribute(simpleCaptcha,map . get(& # 34;斯特朗苏& # 34;) .toString()。toLowerCase());request.getSession()。set attribute(& # 34;codeTime & # 34,新日期()。getTime());试试{ imageio . write((buffered image)map . get(& # 34;图像& # 34;),"JPEG & # 34,0S);]catch(io exception e){ return & # 34;";}返回null}即通过使用页面上的“limages/imagecode”链接,可以返回一个由几个随机数组成的验证码图片。输出验证码时,使用会话保存验证码的数据,为下一步验证验证码提供依据。

关于验证码的验证,其实现代码如下:

@ request mapping(value = & # 34;/check code & # 34;)CResponseBodypublic String checkCode(http servlet request请求,HttpSession会话)抛出异常{ String checkCode = request . getparameter(& # 34;校验码& # 34;);object simple = session . get attribute(& # 34;简单验证码& # 34;);//验证码对象if(simple = = null){ request . set attribute(& # 34;errorMsg & # 34,"验证码已过期。请重新输入!");return & # 34验证码已过期。请重新输入!";string captcha = simple . tostring();Date now = new Date();long code time = long . value of(session . get attribute(& # 34;codeTime & # 34)+"");if(string utils . isempty(check code)l captcha = = null!(check code . equalsignorecase(captcha)){ request . set attribute(& # 34;errorMsg & # 34,"验证码错误!");return & # 34验证码错误!";} else if((now . gettime()-code time)/1000/60 & gt;5)(//验证码的有效长度为5mi request . set attribute(& # 34;errorMsg & # 34","验证码已过期。请重新输入!");return & # 34验证码已过期。请重新输入!";} else { session . remove attribute(& # 34;简单验证码& # 34;);return & # 341";}}}将用户输入的内容与上面会话保存的数据进行比较,如果相同,则可以通过检查。

完成上述设计后,当用户第一次登录失败时,会显示如图10-5所示的登录界面。

商家管理后台(拼多多商家登录入口网页版)

单点登录的主页设计

如果你登录了一个可以访问SSO服务的第三方应用,成功登录后,SSO服务器会根据应用的链接地址返回到相关的应用。如果您登录SSO服务器,默认情况下,您将返回SSO服务器的主页。在主页设计中,我们提供了其他应用程序的链接。

单点登录的主页设计包括两个部分。第一部分是控制器的设计,实现代码如下:

@ controller public class log in controller { @ ReguestMapping(& # 34;/")公共字符串索引(模型映射模型,主体主体)引发异常{ my user details my user details =(my user details)security context holder . get context()。getAuthentication()。get principal();user user = my user details . getuser();//分类列表(顶部菜单)列表< Kind & gtkindList = new ArrayList & lt& gt();列表& ltLong & gtkindIds = new ArrayList & lt& gt();for(role role:user . get roles()){ for(resource resource:role . get resources()){//Duplicate,获取分类列表longkindid = resource.getmodel()。getkind()。getid();如果(!kind ids . contains(kindId)){ kind list . add(resource . get model()。getKind());kindids . add(kindId);} } }模型。add attribute(& # 34;种类& # 34;,kindList);模型。add attribute(& # 34;本金& # 34;,本金);return & # 34首页& # 34;;}}首先通过SecurityContextHolder获取登录用户的完整信息。然后根据登录的用户和用户周围的关系,可以整理出这个用户可以访问的顶层菜单。最后,使用类别列表种类为主页视图提供这个顶级菜单。

第二部分是页面视图设计,在SSO主页home.html的导航部分实现了处理分类列表的设计,代码如下:

<div class="new-icon" th:each="kind: $ {kinds}"><div class="icon-pic"><p><ath:href="${'javascript:gotoService ("'+kind.link+' ", "");')" class="linka" ><img src="/images/home/BigIconFirm. png" /</a></p></div><div class="icon-txt"><dl><dt><p><ath:hrefe"'javascript:gotoService (1''+$(kind.link}+'\',N' ');'" class="linka"th:text="${kind.name}"></a></p><span><imgsrC=" /images/home/FourStar.jpg"/></span></dt></dl></div></div>

这里使用了Thymeleaf的一个循环语句 th:each,将分类列表中包含的每一条记录在页面中展示出来。每条记录都包含一个图像和一个文本链接。其中,对于每一个链接的访问,使用gotoService函数进行页面跳转。& ltdiv class = & # 34新图标& # 34;th:each = & # 34;种类:$ { kinds } & # 34& gt& ltdiv class = & # 34图标-图片& # 34;& gt& ltp & gt& ltath:href = & # 34;${'JavaScript:goto service(& # 34;'+kind . link+& # 39;", "");')"class = & # 34卡琳& # 34;& gt& ltimg src = & # 34/images/home/BigIconFirm。巴新& # 34;/& lt;/a & gt;& lt/p & gt;& lt/div & gt;& ltdiv class = & # 34icon-txt & # 34;& gt& ltdl & gt& ltdt & gt& ltp & gt& ltath:hrefe & # 34;'JavaScript:goto service(1 & # 39;'+$(kind . link }+& # 39;\',N & # 39');'"class = & # 34卡琳& # 34;th:text = & # 34;$ { kind.name } & # 34& gt& lt/a & gt;& lt/p & gt;& ltspan & gt& ltimgsrC = & # 34/images/home/four star . jpg & # 34;/& gt;& lt/span&gt。& lt/dt & gt;& lt/dl & gt;& lt/div & gt;& lt/div & gt;这里,一个循环语句th:each of Thymeleaf用于显示页面上分类列表中包含的每条记录。每条记录包含一个图像和一个文本链接。其中,对于各个链接的访问,使用gotoService函数进行页面跳转。

完成以上设计后,可以进行简单的测试。

启动merchant-sso应用程序,并在浏览器上输入以下链接:http://localhost:8000

打开链接后,就可以进入登录界面。在登录界面输入前面单元测试中生成的用户名和密码,即“admin/123456”。成功登录后,可以打开SSO的首页,如图10-6所示。

商家管理后台(拼多多商家登录入口网页版)

注意:图10-6所示的应用程序列表将由用户的权限决定。如果我们为一个用户指定更多的权限,这个用户将获得更多的访问资源,如图10-7所示。

商家管理后台(拼多多商家登录入口网页版)

本文给大家讲解的内容商家管理后台与sso设计: SSO设计下篇文章给大家讲解的是商家管理后台与sso设计:SSO客户端设计;觉得文章不错的朋友可以转发此文关注小编;感谢大家的支持!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/30010.html

发表回复

登录后才能评论