③. 入门案列出现的问题
3>.
入门案例出现的问题及解决方案
①. 项目中我们将所有的资源(所有请求URL)都保护起来,实际环境下往往有一些资源 不需要认证也可以访问,也就是可以匿名访问
②. 登录页面是由框架生成的,而我们的项目往往会使用自己的登录页面
③.直接将用户名和密码配置在了配置文件中,而真实生产环境下的用户名和密码往往保 存在数据库中
④. 在配置文件中配置的密码使用明文,这非常不安全,而真实生产环境下密码需要进行 加密
①. 配置可匿名访问的资源
1.
配置可匿名访问的资源
- ①. 在项目中创建pages目录,在pages目录中创建a.html和b.html
- ②. 在spring-security.xml文件中配置,指定哪些资源可以匿名访问
<!--配置哪些资源匿名可以访问(不登录也可以访问)--> <!-- <security:http security="none" pattern="/pages/a.html"></security:http> <security:http security="none" pattern="/pages/b.html"></security:http>--> <security:http security="none" pattern="/pages/**"/>
- ③.通过上面的配置可以发现,pages目录下的文件可以在没有认证的情况下任意访问
②. 使用指定的登录页面
2.
使用指定的登录页面
①. 提供login.html作为项目的登录页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页面</title> </head> <body> <h3>自定义登录页面</h3> <form action="/login.do" method="post"> username:<input type="text" name="username"><br> password:<input type="password" name="password"><br> <input type="submit" value="登录"> </form> </body> </html>
②. 修改spring-security.xml文件,指定login.html页面可以匿名访问
<security:http security="none" pattern="/login.html" />
③. 修改spring-security.xml文件,加入表单登录信息的配置
<!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表 单.页面提交的登录表单请求是由框架负责处理--> <!-- login-page:指定登录页面访问URL default-target-url="/index.html" 登录成功了默认跳转到index.html --> <security:form-login login-page="/login.html" username-parameter="username" password-parameter="password" login-processing-url="/login.do" default-target-url="/index.html" authentication-failure-url="/login.html"></security:form-login>
④.修改spring-security.xml文件,关闭CsrfFilter过滤器
<!-- csrf:对应CsrfFilter过滤器 disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则 登录操作会被禁用(403) --> <security:csrf disabled="true"></security:csrf>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!--配置哪些资源匿名可以访问(不登录也可以访问)--> <!-- <security:http security="none" pattern="/pages/a.html"></security:http> <security:http security="none" pattern="/pages/b.html"></security:http>--> <security:http security="none" pattern="/pages/**"/> <security:http security="none" pattern="/login.html"></security:http> <!-- auto-config:自动配置,如果设置为true,表示可以自动应用一些配置,比如框架会提供一个默认的登录页面 use-expressions:是否使用spring security提供表达式来描述权限 --> <security:http auto-config="true" use-expressions="true"> <!-- 配置拦截规则,/**表示拦截所有请求 pattern:来描述拦截规则 access:指定所需的访问角色、访问权限 注意:use-expressions 和 access 相匹配的 如果use-expressions=false,则access=“‘ROLE_ADMIN’” --> <security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"></security:intercept-url> <!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表单.页面提交的登录表单请求是由框架负责处理--> <!-- login-page:指定登录页面访问URL default-target-url="/index.html" 登录成功了默认跳转到index.html --> <security:form-login login-page="/login.html" username-parameter="username" password-parameter="password" login-processing-url="/login.do" default-target-url="/index.html" authentication-failure-url="/login.html"></security:form-login> <!-- csrf:对应CsrfFilter过滤器 disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403) --> <security:csrf disabled="true"></security:csrf> </security:http> <!--认证管理器 --> <security:authentication-manager> <!--配置认证的提供者--> <security:authentication-provider> <security:user-service> <!--配置一个具体的用户,后期需要从数据库查询用户--> <security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/> </security:user-service> </security:authentication-provider> </security:authentication-manager> </beans>
③. 从数据库中查询用户信息
3.
从数据库中查询用户信息[模拟数据]
①.SpringSecurityUserService
public class SpringSecurityUserService implements UserDetailsService { //模拟数据库中的用户数据 public static Map<String, User> map = new HashMap<String, User>(); static { com.itheima.pojo.User user1 = new com.itheima.pojo.User(); user1.setUsername("admin"); user1.setPassword("admin");//明文密码(没有加密) com.itheima.pojo.User user2 = new com.itheima.pojo.User(); user2.setUsername("xiaoming"); user2.setPassword("1234"); map.put(user1.getUsername(),user1); map.put(user2.getUsername(),user2); } //根据用户名查询用户信息 //UserDetails[接口]它的实现类是User public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //System.out.println("用户输入的用户名是"+username); //1.根据用户名查询数据库,来获得用户信息(包括数据库中存储的密码字段) User user = map.get(username);//模拟根据用户名查询数据库 if(user==null){ //用户名不存在 return null; }else { //用户名存在 //2.将用户信息返回给框架 List<GrantedAuthority>list=new ArrayList<GrantedAuthority>(); //当前登陆用户授权,后期需要改为从数据库查询当前用户对应的实际权限 list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));//授予角色 list.add(new SimpleGrantedAuthority("permission_A"));//授予权限 list.add(new SimpleGrantedAuthority("permission_B"));//授予权限 //2.1框架会进行密码比对(页面提交的密码和数据库中查询的密码进行比对) org.springframework.security.core.userdetails.User securityUser =new org.springframework.security.core.userdetails.User(username,"{noop}"+user.getPassword(),list); return securityUser; } } }
②.spring-security.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!--配置哪些资源匿名可以访问(不登录也可以访问)--> <!-- <security:http security="none" pattern="/pages/a.html"></security:http> <security:http security="none" pattern="/pages/b.html"></security:http>--> <security:http security="none" pattern="/pages/**"/> <security:http security="none" pattern="/login.html"></security:http> <!-- auto-config:自动配置,如果设置为true,表示可以自动应用一些配置,比如框架会提供一个默认的登录页面 use-expressions:是否使用spring security提供表达式来描述权限 --> <security:http auto-config="true" use-expressions="true"> <!-- 配置拦截规则,/**表示拦截所有请求 pattern:来描述拦截规则 access:指定所需的访问角色、访问权限 注意:use-expressions 和 access 相匹配的 如果use-expressions=false,则access=“‘ROLE_ADMIN’” --> <security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"></security:intercept-url> <!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表单.页面提交的登录表单请求是由框架负责处理--> <!-- login-page:指定登录页面访问URL default-target-url="/index.html" 登录成功了默认跳转到index.html --> <security:form-login login-page="/login.html" username-parameter="username" password-parameter="password" login-processing-url="/login.do" default-target-url="/index.html" authentication-failure-url="/login.html"></security:form-login> <!-- csrf:对应CsrfFilter过滤器 disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403) --> <security:csrf disabled="true"></security:csrf> </security:http> <!--认证管理器 --> <security:authentication-manager> <!--配置认证的提供者--> <security:authentication-provider user-service-ref="userService"/> </security:authentication-manager> <bean id="userService" class="com.itheima.service.SpringSecurityUserService"></bean> </beans>