想省事就这样配置:
[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的认证过程,找到其登录过程和跳转机制
参考如下
[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,我们怎么写数据呢,回本溯源,直接使用servlet的print方法即可。
实现这个之后,只要通过项目的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贝明实验室
再接着这个说一句,如果跨域需要自己造轮子,或者容器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的多,和传统md5的hash加密不同,他的执行慢,解密成本大,所以用时间换了安全。
上面代码注释的部分,就是加密的部分,是md5的salt加密方式
如果我们想要的数据,根本不在可获知的数据源上,我们只有接口,或者说,我们用户的提供方式,想自己写,那怎么办呢
自定义
要了解自定义,就得知道。在哪里进行认证的 dao
根据
[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,所以我们就只有过滤出资源的角色,然后和用户的角色进行比对,通过就放行即可
相关的实现类,仍然是根据
[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/
所以我们继承实现相关url的角色实现和角色比对类就可以了