1、在web.xml中配置spring security的过滤器代理: filter-class = org.springframework.web.filter.DelegatingFilterProxy,
这个代理会把过滤到请求自动转到 springSecurityFilterChain 这个类里面,这个是spring security的一个处理类
这个过滤器要配置 <filter-name>springSecurityFilterChain</filter-name> 这里的name固定要是springSecurityFilterChain,因为他是security内置好的过滤器名称
2、在spring配置文件中加入spring security的配置(这里加入一个配置文件,用来配置security相关–spring-security.xml)
a).在spring-security.xml中配置spring security的页面拦截规则:
<!-- security的页面拦截规则, use-expressions表示是否启用SPEL表达式,默认是true -->
<http use-expressions="false">
<!-- 拦截的路径: /* 表示只拦截根目录下的资源,不包括它子目录的资源; /** 就是包括所有的资源 -->
<!-- access 配置security的角色名,security规定角色名必须是ROLE_开头的(如果上面不配置use-expressions=false,这里就要写成 hasRole(ROLE_USER')) -->
<intercept-url pattern="/**" access="ROLE_USER"/>
<!-- 开启表单登录功能 -->
<form-login/>
</http>
b).在spring-security.xml中配置认证管理器
<!-- 认证管理器 -->
<authentication-manager>
<!-- 认证的提供者 -->
<authentication-provider>
<user-service>
<!-- user用来配置当前系统的用户,name就是用户的name,authorities是角色名 -->
<!-- 这个配置的意思是:配置一个用户admin,密码是123456,角色是ROLE_USER,如果admin登录之后,就能访问ROLE_USER这个角色配置的资源,如果不是这个用户登录,或者没有登录,就不能访问 -->
<user name="admin" password="123456" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
3、启动项目,访问项目(如果没有自己写登录页面),因为在spring-security.xml配置了 (开启表单登录功能),所以spring security会帮我们自动生成一个登陆页面。
如果不登录,直接访问index.html,会跳转到这个登陆页面,如果不使用 admin 123456登陆,也会提示登陆失败,只有使用admin 123456登陆后,才能跳转到index.html页面
4、使用自己定义的登录页面,配置详细看spring-security.xml文件
<!-- 以下页面不登录也能访问 -->
<http pattern="/login.html" security="none"/>
<http pattern="/login_error.html" security="none"/>
5、在拦截规则中,加入,表示关闭拦截csrf拦截机制
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用,如果是jsp页面,那每个页面都会自带csrf
在html页面中,也可以在js代码中,给请求添加csrf头信息,适用于发送ajax请求
6、上述的做法在登录的时候没有查询数据库,而是在spring security配置文件中写死的username,password,下面是从数据库查询用户进行spring security的登录:
a). pom.xml,web.xml,login.html中的form表单里面的写法都同上面一样
b). 写一个UserDetailsServiceImpl 继承 UserDetailsService,这是security认证接口的实现类,UserDetailsService是security自己定义的一个认证类,
这里要实现里面一个方法,loadUserByUsername(String username),当用户在页面登录后,通过security的配置,请求会自动进入到这个方法里面
c). public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
System.out.println("经过了UserDetailsServiceImpl...");
//grantAuths是表示这个用户在security认证之后的角色的集合
List<GrantedAuthority> grantAuths = new ArrayList<GrantedAuthority>();
//这个list里面要放GrantedAuthority对象,但是它是一个接口,所以放它的实现类 SimpleGrantedAuthority
grantAuths.add(new SimpleGrantedAuthority("ROLE_SELLER")); //security规定角色名必须是ROLE_ 开头
//这个User类也是security定义的一个类,它是 UserDetails 的实现类
//这个返回的User的意思是,当用户登录输入的用户名=username,密码=123456时,就登录成功,反之不成功(username和123456应该是从数据库查出来的)
User user = new User(username, "123456", grantAuths);
return user;
}
d). 当用调用服务层的应用访问数据库时,需要一个sellerService对象:
/**调用服务层访问数据库,来查询用户*/
private SellerService sellerService;
/**因为当前类所在的包不在controller里面,所以不能dubbo的@Reference来注入对象,这里采用spring配置文件的形式注入对象,所以这里要提供一个set方法*/
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
e). <!-- 自定义的认证接口的实现类 -->
<bean:bean id="userDetailService" class="com.pinyougou.service.UserDetailsServiceImpl">
<!-- 这里使用spring配置文件的bean注入sellerService对象,这里的name和和UserDetailsServiceImpl里面的属性名一样 -->
<bean:property name="sellerService" ref="sellerService"/>
</bean:bean>
<!-- 采用dubbo,从远程引入一个sellerService的对象,id就是对象的名字 -->
<dubbo:application name="pinyougou-shop-web" />
<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
<dubbo:reference interface="com.pinyougou.sellergoods.service.SellerService" id="sellerService"/>