讲义参考成果_第1页
讲义参考成果_第2页
讲义参考成果_第3页
讲义参考成果_第4页
讲义参考成果_第5页
免费预览已结束,剩余31页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章用户认上面流程图描述了用户要操作的各个微服务,用户查看个人信息需要客户微服务,下单需要订单微服务,秒杀抢购商品需要秒杀微服务。每个服务都需要认证用户的,认证成功后,需要识别用户的角色然后对应的功能。单点登用户的项目中,至少有3个微服务需要识别用户,如果用户每个微服务都登录一次就太麻烦了,为了提高用户的体验,我们需要实现让用户在一个系统中登录,其他任意受信任的系统都可以访问,这个功能就叫单点登录。单点登录(SingleSignOn),简称为SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的第账号登随着国内及国外巨头们的平台开放以及移动互联网的发展,第登录已经不是一个陌生的产品设计概念了。所谓的第登录,是说基于用户在第平台上已有的账号和来快速完成己方应用的 等,国内的比如、、QQ等222.1单点登录技术方Java中有很多用户认证的框架都可以实现单点2.22.2登录技术方1、ApacheShiro.3、SpringOauth2认证第认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。AUH协议为用户资源的提供了一个安全的、开放而又简易的标准。同时任何第都可以使用AUH认证服务,任何服务提供商都可以实现自身的AUH认证服务,因而AUH是开放的。业界提供了AUH的多种实现如PP、JvScip,Java,Ruy等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。互联网很多服务如OpenAPI,很多大公司如 资源的标准。Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。参 ?fr=aladdinOauth协议:ml/rfc6749下边分析一个Oauth2认证的例子,程序员使用 ,开始 会对资源拥有者的进行验证,验证权,QQ认证服务器会颁发一个码,并重定向到程序员的3.3.客户端获取到 码,请求认证服务器申请令牌此过程用户看不到,客户端应用程序请求认证服务 员看到已经登录成功客户端请求资源服务器的资源客户端携带令牌资源服务器的资源。程序员携带令牌请求服务器获取用户的基本信息。资源服务器返回受保护资源资源服务器校验令牌的,如果合法则向用户响应资源信息内容。注意:资源服务器和认证服务器可以是一个服务也可以分开的服务,如果是分开的服务资源服务器通常要请求认证服务器来校验令牌的。Oauth2.0认证流程如下:引自Oauth2.0协议rfc67491、客户端本身不资源,需要通过资源拥有者的去请求资源服务器的资源,比如:畅 2、资源拥有者通常为用户,也可以是应用程序,即该资源的3、服务器(也称认证服务器)用来对资源拥有的进行认证、对资源进行。客户端要想资源需要通过认证服务器由资源拥有者授权后方可。4、资源服务器资源的服务器,比如,畅购用户管理服务器了畅购的用户信息, Oauth2在项目的应Oauth2可以实现实现如下功能1、本系统第系统的资3、本系统前端(客户端)本系统后端微服务的资源4、本系统微服务之间资源,例如:微服务A微服务B的资源,BA的资源2.3SpringsecurityOauth2认证解决本项目采用Srigscrity+JW完成用户认证及用户,Srigscrity是一个强大的和高度可定制的验证和控制框架,Srigscrity框架集成了Oath协议,下图是项目认证架构图:2、认证服务下发用户令牌,拥有令牌表示合法4、网关校验用户令牌的合法,不合法表示用户没有登录,如果合法则放行继续6、资源服务完成则响应资源信息Jwt令牌JSONWebToken(JWT)是一个开放的行业标准(RFC7519),它定义了一种简介的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。JWT可以使用 HMAC算法或使用RSA的公钥/私钥对来签名,防止被篡改。4、资源服务使用JWT可不依赖认证服务即可完 2、以2、以在令牌自定义富的内容,易展。{{"sub":""name":"admin":}3.1令牌结头部包括令牌的类型(即JWT)及使用的哈希算法(如HMACSHA256或RSA)第二部分是负载,内容也是一个jso对象,它是存放有效信息的地方,它可以存放jw如:s(签发者)xp(过期时间戳),su(面向的用户)等,也可自定义字段。此部分不建议存放敏感信息,因为此部分可 {"alg":"typ":}1、JWT令牌较长, 空间比较大签名算法进行签名。一个例子base6UrlEncode(header)+.base64UrlEncode(header):jwt令牌的第一部分。base64UrlEncode(payload):jwt令牌的第二部分。base6UrlEncode(header)+.生成私钥公1、生成密钥下边命令生成密钥,采用RSA算法每个包含公钥和私KeytoolKeytool是一个java提供 查 keytool-list-keystore-alias:密钥的别-keyalg:使用的hash算-keypass:密钥-keystore:密钥库文件名,changgou.jks保存了生-storepass:密钥库keytool-genkeypair-aliaschanggou-keyalgRSA-keypasschanggou-keystorechanggou.jks-storepasschanggou2、导出公安 执行如下命令keytoolkeytool-list-rfc--keystorechanggou.jks|opensslx509-informpem- -----BEGINPUBLICKEY---- -----ENDPUBLICKEY----基于私钥生成jwt令将课件中changgou_user_auth的工程导入到项目中去,如下publicpublicclassCreateJwtTest*创建令牌测试publicvoid 文件路String//String//秘Stringkeypwd=//秘钥别Stringalias=路ClassPathResourceresource=new//创建秘钥工KeyStoreKeyFactorykeyStoreKeyFactory=new KeyPairkeyPair=//获取私RSAPrivateKeyrsaPrivate=(RSAPrivateKey)//定义Map<String,Object>tokenMap=newHashMap<>();tokenMap.put("id","1");tokenMap.put("name","itheima");tokenMap.put("roles","ROLE_VIP,ROLE_USER");//生成Jwt令//取出令Stringencoded=jwt.getEncoded();}}基于公钥解析jwt令在chan 创建测试类 .chaggo.toePsJwtst实现解析校验令牌据,代码如下:publicpublicclassParseJwtTest*校验令牌publicvoid//令Stringtoken=//公Stringpublickey="-----BEGINPUBLICKEY----- PUBLIC //校验Jwtjwt=JwtHelper.decodeAndVerify(token,new//获取Jwt原始内Stringclaims=jwt.getClaims();//jwt令Stringencoded=jwt.getEncoded();}}Oauth2.04.1准备工1)搭建认证服务器之前,先在用户系统表结构中增加如下表结`resource_ids``resource_ids`varchar(256)DEFAULT`client_secret`varchar(256)DEFAULTNULLCOMMENT'客户端秘钥,`scope`varchar(256)DEFAULTNULLCOMMENT'对应的范围`authorized_grant_types`varchar(256)DEFAULTNULLCOMMENT'认证模式`web_server_redirect_uri`varchar(256)DEFAULTNULLCOMMENT'认证后重定向地址`authorities`varchar(256)DEFAULT`access_token_validity`int(11)DEFAULTNULLCOMMENT'令牌有效期`refresh_token_validity`int(11)DEFAULTNULLCOMMENT'令牌刷新周期`additional_information`varchar(4096)DEFAULT`autoapprove`varchar(256)DEFAULTNULL,PRIMARYKEY(`client_id`))ENGINE=InnoDBDEFAULT4.24.2 模式介Oauth2有以 码模式(Authorization隐 模式模式(ResourceOwnerPassword客户端模式(ClientINSERTINTO`oauth_client_details`VALUES('changgou',null,'$2a$10$Yvkp3xzDcri6MAsPIqnzzeGBHez1QZR3A079XDdmNU4R725KrkXi2','app', ',null,'43200','43200',null,其中码模式和模式应用较多,本小节介绍码模式4.2.1码模码流1、客户端请求3、客户端获取到码,请求认证服务器申请令5、客户端请求资源服务器的资源,资源服务校验令牌,完请请求认证服务获 client_id:客户端id, 配置类中设置的客户端id一致 redirect_uri:跳转uri, 码申请成功后会跳转到此地址,并在后边带上code参数 码Get?首先跳转到登录页面输入账号和 ,点击i。SrigSecuiy接收到请求会调用UsrDtlsService接口的lUsrByUsra方法查询用户正确的。当前导入的基础工程中客户端D为cag也为cag即可认证通过。点击点击Atoriz,接下来返回 码:认证服务携带 码跳转eiect_ur,code=k45iY就是回的授权码,每一个 码只能使用一次申请拿到码后,申请令牌Post请求 类型,填写authorization_code,表 码模 码,就是刚刚获取 码,注意 码只使用一次就无效了,需要重新申请redirect_uri:申 码时的跳转url,一定和申 码时用的redirect_uri一致此需要使用httpBasic认证。什么是httpBasic认证?base64编码,放在header中请求服务端,一个例子:Athorization:BsicWZWJBcA6NZWJBcA=NZWJBcA6ZWJBcA=名:的bse64编码。认证失败服务端返回401Unauthorized。httpbasic认证客户端Id和客户 会匹客户端Id和客户 会匹配数据库oauth_client_details表中的客户端id及客户 返返回信如下用用BearerToken(http:/ token_type:有MACtoken_type:有MACokenBeareroken种类型,种的校验算法同,RC6750建议Oauth2SpringSecurityOauth2提供校验令牌的Get:token?token=参数token使用postman测试如下如果令牌校验失败,会出现刷新 固定 refresh_token:刷新令牌(注意不是access_token,而是4.2.2模模式(ResourceOwnerPasswordCredentials)与码模式的区别是申请令牌不再使用码,而是直接通过用户名和即可申请令牌。申请令牌PostPost请求携带参数 并且此需要使用httpBasic认证测试数据如下4.3资源服资源服务拥有要的受保护资源,客户端携带令牌资源服务,如果令牌合法则可成功资源服务中的资源,如下图:上图上图的业务流程如下4.3.1用户服务对接1、客户端请求认证服务申请令2、认证服务生成令牌认证服务采用非对称加密算法,使用私钥生成令 资源服务客户端在Httpheader中添加:Authorization:Bearer令牌。 5、令牌有效,资源服务向客户端响应资源信基本上所有微服务都是资源服务,这里我们在课程管理服务上配置控制,当配置了控制后如课程信息则必须提供令牌。2、添加依 @EnableGlobalMethodSecurity(prePostEnabled=true,securedEnabled=true)//激活方publicclassResourceServerConfigextendsResourceServerConfigurerAdapter//公privatestaticfinalStringPUBLIC_KEY=定义@parampublicTokenStoretokenStore(JwtAccessTokenConverterjwtAccessTokenConverter){returnnew}定义publicJwtAccessTokenConverterreturn}获取非对称加密公钥<artifactId>spring-cloud-starter-privateprivateStringgetPubKey()Resourceresource=newClassPathResource(PUBLIC_KEY);try{InputStreamReaderinputStreamReader=newreturnbr.lines().collect(Collectors.joining("\n"));}catch(IOException{return}}Http安全配置,对每个到达系统的http请 进行校@param@throwspublicvoidconfigure(HttpSecurityhttp)throwsException//"/user/add").// 址放 //}}4.3.2资源服务测不携带令由于该地址受限制,需要,所以出现如下错误{{"error":"error_description":"Fullauthenticationisrequiredtoaccessthis}携带在httpheader中添加Authorization:Bearer11、用户登录,请求认证服2、认证服务认证通过,生成jwt令牌,将jwt令牌及相关信息写入Redis,并且 令牌写3、用 资源页面,带 到网4、网关 获取token,并查询Redis校验token,如果token不存在 ,否则放5、用户退出,请求认证服务,清除redis中的token,并且删 中的当输入错误的令牌也无法正当输入错误的令牌也无法正 需求分功能流程图如下执行流执行流程使用 用客户客户 2、由jwt令牌过2、由jwt令牌过长,宜,所以将jwt在在redis,由客户端请求服务端获取并在将认证服务changgou_user_auth中的aplicatio.yl配置文件中的Rs配置改成自己对应的端口和密码。认证服认证服务需要实现的功能如1、登录接 将令牌写。2、退出接口校验当前用户的为合法并且为已登录状态。将令牌从redis删除。删除 ttl:1200#token clientId:changgou clientSecret:changgou#客户端秘钥: 保存对应MaxAge:- 过期时间,-1表示浏览器关闭则销为了不破坏SrigSecuiy的代码,我们在Svic方法中通过estemlat请求SrigSecrty露的申请令牌接口来申请令牌,下边是测试代码:publicprivateLoadBalancerClientprivateRestTemplate*发送Http请求创建令publicvoidtestCreateToken()throwsInterruptedException//采用客户端负载均衡,从eureka获取认证服务的ip和端ServiceInstanceserviceInstance=

URIuri=//申请令牌地StringauthUrl=uri+//1、header信息,包括了httpbasic认证信MultiValueMap<String,String>headers=newLinkedMultiValueMap<String,//进行Base64编码,并将编码后的认证数据放到头Stringhttpbasic=httpbasic("changgou","changgou");headers.add("Authorization",httpbasic);//2、指定认证MultiValueMap<String,String>body=newLinkedMultiValueMap<String,HttpEntity<MultiValueMap<String,String>>(body,headers);//指 restTemplate当遇到400或401响应时候也不要抛出异常,也要正常返回restTemplate.setErrorHandler(new{IOException{//当响应的值为400或401时候也要正常响应,不要抛出if(response.getRawStatusCode()!=400&&response.getRawStatusCode()!=401){}} 调用申请令ResponseEntity<Map>exchange=restTemplate.exchange(authUrl,HttpMethod.POST,multiValueMapHttpEntity,Map.class);Mapresult=exchange.getBody();}@param@paramprivateStringhttpbasic(StringclientId,String//将客户端id和客户 拼接,按“客户端id:客户 Stringstring=//进行base64byte[]encode=Base64Utils.encode(string.getBytes());return"Basic"+newString(encode);}}AuthServiceImplAuthServiceImpl实现publicclassAuthServiceImplimplementsAuthServiceprivateRestTemplateprivateLoadBalancerClientprivateStringRedisTemplateprivatelongttl;申请@param@param@param@parampublicAuthTokenapplyToken(Stringusername,Stringpassword,StringclientId,StringclientSecret){publicinterfaceAuthServiceAuthTokenlogin(Stringusername,Stringpassword,StringclientId,String}URIuri=serviceInstance.getUri();Stringurl=uri+"/oauth/token";MultiValueMap<String,String>body=newLinkedMultiValueMap<>();MultiValueMap<String,String>headers=newLinkedMultiValueMap<>();DefaultResponseErrorHandler(){@OverrideIOException{if(response.getRawStatusCode()!=400&&}}ResponseEntity<Map>responseEntity=restTemplate.exchange(url,HttpMethod.POST,requestEntity,Map.class);Mapmap=if(map==null||map.get("access_token")==null||map.get("refresh_token")==null||thrownewRuntimeException("申请令牌失败}AuthTokenauthToken=newAuthToken();authToken.setAccessToken((String)map.get("access_token"));authToken.setRefreshToken((String)map.get("refresh_token"));authToken.setJti((String)map.get("jti"));ken(),ttl,TimeUnit.SECONDS);return}privateStringgetHttpBasic(StringclientId,StringclientSecret)Stringvalue=byte[]encode=Base64Utils.encode(value.getBytes());return"Basic"+newString(encode);}} publicclass publicclassAuthControllerprivateAuthServiceprivateStringprivateStringprivate;privatepublicResultlogin(Stringusername,StringifthrownewRuntimeException("用户名不存在}ifthrownew 不存在}AuthTokenauthToken=returnnewResult(true,StatusCode.OK,"登录成功}privatevoid(String{HttpServletResponseresponse= }使用postman1Post请求当前在认证服务中,用户是写死在用户认证类中。所以用户登录时,无论帐号输入什么,只要是h都可以。因此需要动态获取用户帐号与.定义被接用户微服务对外根据用户名获取用户信息接publicUserfindUserInfo(@PathVariable("username")Stringusername){returnuserService.findById(username);}放行该接口,修改ResourceServerConfig定义feign接publicinterfaceUserFeignpublicUserfindUserInfo(@PathVariable("username")String}认证服务添加依修改认证服务启修改用户认证@EnableFeignClients(basePackages=<version>1.0-测试测试:重新启动服新建网关工程<artifactId>spring-cloud-starter-<artifactId>spring-cloud-starter-netflix-<artifactId>spring-cloud-starter-netflix-eureka-<!--redis--<artifactId>spring-boot-starter-data-redis-3)3)创建name:gateway-web'[/**]':#匹配所有请求allowedOrigins:"*"#跨域处理允许所有的域allowedMethods:#-id:changgou_goods_routeuri:lb://goodspublicclassWebGateWayApplicationpublicstaticvoidmain(String[]{}}#-StripPrefix=1id:changgou_user_routeuri:lb://user-id:changgou_oauth_useruri:lb://user-authhost:prefer-ip-address:trueenabled:trueinclude:true网关全局过滤新建过滤器类新建过滤器类AuthorizeFilter,业务逻辑2)判断中是否存在信息,没有的话publicpublicclassAuthFilterimplementsGlobalFilter,OrderedpublicstaticfinalStringAuthorization=privateAuthServicechain){//获取当前请求对ServerHttpRequestrequest=excha

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论