Quantcast
Channel: PayMoon贝明实验室
Viewing all articles
Browse latest Browse all 130

[Spring Security 4][实战]第二个定制化的案例

$
0
0
第一个案例在此 然后在说这个案例时,我们还是依赖[权限]权限的原理[SS4层面]SS4是如何把权限实现的原理,下面先说下问题 一是login页面,样式我们会想自定义,二是用户信息,我们不能配置在xml里面了。 说下这两个问题解决: login/logout页面配置 仍然是在applicationContext-security里面配置 <http>form-login配置login, [crayon-584d49a296b16763647526/] 配置完后我们不希望login.jsp需要权限于是 [crayon-584d49a296b23301286878/]

想省事就这样配置:

[crayon-584d49a296b29623092543/]

这两个效果不太一样,access是能获取用户信息的,security则就相反了,用户信息会被忽略,这两个配置很有用,下面会讲到。

完整配置如下:

[crayon-584d49a296b2e092233967/]

相关页面代码

login.jsp [crayon-584d49a296b34624271130/] [crayon-584d49a296b39219481130/] 两个方法都是post请求,大家会注意到一个地方: <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 这个就是CSRF了,与SS3不同,他是SS4里面默认都会开启的,为了安全,防止恶意的CSRF攻击,Spring Security需要校验form表单中的hidden域提交的内容。 关于CSRF可以插播一下,他是什么东东 [Spring Security 4]CSRF攻击方式/防御/使用 – PayMoon贝明实验室 www.paymoon.com:8001/index.php/2016/12/08/csrf-attack-and-defence/

当然,因为开启了CSRF,需要在每次提交数据里面都加上CSRF,如果你有别的安全措施,或者不想加,可以在xml里面不用的,方法如下:

<csrf disabled="true"/>

否则如果不加hidden这一段会报错

登录的问题好像解决了,但是,如果我们的其它服务,是模块化的,或者说是分步式设计的,可能你想用的页面,根本就没在这个项目下,甚至都不在一个机器上,这时候调不了login.jsp了,怎么办?

登录的用户名不是username/password怎么办

那我们就只能提供服务了,提供能够返回类似json这种数据格式的服务,也就是前端调用我们提供的login服务,我们返回成功与否的判断+数据。

这就要自定义认证过程了

在重写之前

我们需要重新看一下SS4的认证过程,找到其登录过程和跳转机制

参考如下

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

可知我们需要继承实现UsernamePasswordAuthenticationFilter

先上一下实现配置过程

[crayon-584d49a296b42400859067/] 我们在把filter加在login的时候用,需要用到

<b:property name="filterProcessesUrl" value="/login" />

<custom-filter ref="myAuthenticationFilter" position="FORM_LOGIN_FILTER" />

这样我们就可以在自定义handler里面做自定义跳转了

那么怎么跳转呢

还记得Successhanlder吗

[crayon-584d49a296b4a181097493/]

需要把我们的数据,序列化为json,就可以了。

问题来了,

因为这里面没有springmvc,我们怎么写数据呢,回本溯源,直接使用servletprint方法即可。

实现这个之后,只要通过项目的login就可以走进登录,并且校验通过或者失败后,就会返回我们预期的json

关于跨域的解决办法,我有写过博客,大家可以参考

JAVA WEB支持CORS 跨域访问 – PayMoon贝明实验室

http://www.paymoon.com:8001/index.php/2016/05/30/java-web-support-cors-visit/

跨域问题的解决办法Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. – PayMoon贝明实验室

http://www.paymoon.com:8001/index.php/2016/11/23/request-header-field-content-type-is-not-allowed-by-access-control-allow-headers-in-preflight-response/

再接着这个说一句,如果跨域需要自己造轮子,或者容器tomcat版本低还不支持,可以自己写filter解决跨域问题。

print方法如下,Access-Control-Allow-Origin是域名过滤,下面的一些参数是支持的header, Method等

[crayon-584d49a296b53801042959/]

这样登陆的问题,从界面到分布式我们就解决了。

该用户来源的问题了:

我们如何自定义数据来源

如:从数据库中获取

刚刚说到,用户来源问题是provider里面提供的,可以看标签,那我们就可以在这里面自定义provider,我们先说通过数据库的方式

先看一下之前xml的方式

[crayon-584d49a296b59110946908/]

user-service就是我们说的provider,如果我们想自定义,

需要先在配置文件里面配置好数据源,然后通过sql的方式,加载数据,

配置好数据源

[crayon-584d49a296b5f382560242/]

数据模型这里也提供了一份,可以看github上,模型就是按照我们之前介绍的权限模型,有初始化的数据,

配置文件sql写法

[crayon-584d49a296b65948970682/]

在这种情况下我们看下密码加密方式

密码加密有可逆和不可逆,很多,这里不是重点,不过提一下,spring4最近使用bcrpt的多,和传统md5hash加密不同,他的执行慢,解密成本大,所以用时间换了安全。

上面代码注释的部分,就是加密的部分,是md5的salt加密方式

如果我们想要的数据,根本不在可获知的数据源上,我们只有接口,或者说,我们用户的提供方式,想自己写,那怎么办呢

自定义

要了解自定义,就得知道。在哪里进行认证的 dao

根据

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

所以我们继承实现UserDetailsService类就可以了

从父类得知,在这个类里面我们把用户提取出来,并且也提供出来角色,这个后面会用到以及是否锁定,账号是否过期等

从这个类和刚刚的UsernamePasswordAuthenticationFilter类,我们可以得知,密码加密的方法不在配置,而是在程序里面做就行了,这样也方便了我们自定义密码加密。

从这里面获取的用户,我们可以生成用户token,然后存储在集中式的缓存服务器上,保证用户的单点登录。

单点的话以后更新..

这就解决了用户认证,分布式,密码加密等的诸多过程

然后就是授权过程。

授权过程

我们的用户已经有了provider,所以我们就只有过滤出资源的角色,然后和用户的角色进行比对,通过就放行即可

相关的实现类,仍然是根据

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

所以我们继承实现相关url的角色实现和角色比对类就可以了


Viewing all articles
Browse latest Browse all 130

Trending Articles