前面我们用了简单的三步就完成了一个Spring- Secutiry的搭建,主要是通过添加auto-config属性和http元素实现的,但是在实际工作中要比这个复杂的太多,现在我们按部就班的来完善我们的权限管理,遇到理论问题,可以去查看专家博客:http://lengyun3566.iteye.com/blog关于Spring Secutiry3翻译。
现在我们为我们JBCP Pets在线商店完善一下,我们先配置自己默认的登录界面,有兴趣的可以从网上找一个,这里我不用书上的登录界面,我从网上找的模板。
在WebContent下创建views文件夹,下面创建 login.jsp(样式见附件),关于登录页注意一下两点:
Form action必须与UsernamePasswordAuthenticationFilter过滤器的action的配置相一致。默认的form action是j_spring_security_check;
用户名和密码的表单域要与servlet的标准相一致。默认j_username和j_password是文本域的名字。
需要注意的是,必须使用post方式的form提交,否则UsernamePasswordAuthenticationFilter会拒绝登录请求。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/base/taglibs.jsp"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Login Form</title> <link rel="stylesheet" href="${cms}/css/style.css"> </head> <body> <section class="container"> <div class="login"> <h1>Login to Web App</h1> <form method="post" action="/j_spring_security_check"> <p><input type="text" name="j_username" value="" placeholder="用户名"></p> <p><input type="password" name="j_password" value="" placeholder="密码"></p> <p class="remember_me"> <label> <input type="checkbox" name="remember_me" id="remember_me"> Remember me on this computer </label> </p> <p class="submit"><input type="submit" name="commit" value="Login"></p> </form> </div> <div class="login-help"> <p>Forgot your password? <a href="index.html">Click here to reset it</a>.</p> </div> </section> </body> </html>
创建SpringMVC的控制器类BaseController和LoginController
package com.pet.Controller; import org.springframework.stereotype.Controller; /** * * @author zangyn * @date 2016-11-22 下午2:34:28 * @Description: 用来提供公共功能 * @throws */ @Controller public class BaseController { }
package com.pet.Controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * * @author zangyn * @date 2016-11-22 下午2:34:48 * @Description: 登录功能控制器 * @throws */ @Controller public class LoginController extends BaseController{ @RequestMapping(method=RequestMethod.GET,value="/login.do") public void home() { } }
这里我们写代码要考虑到控制器类可能存在需要公用的功能,所以构造BaseController这个类来放置重复使用的方法。现在就要将控制器加入SpringMVC容器中,所以需要修改SpringMVC的配置文件,通过扫描加入注解后的类和方法。
<?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:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 自动扫描注解标注的类或方法 --> <context:component-scan base-package="com.pet"/> </beans>
@RequestMapping标注的方法如果返回空值,则返回的逻辑视图名为value的值,因此上面
@RequestMapping(method=RequestMethod.GET,value="/login.do") public void home() { }
实际返回的是URL= prefix前缀+视图名称 +suffix后缀组成,这样就会返回我们在views下的login.jsp.
现在我们配置web.xml下的<welcome-file-list>值为login.do,这样就能调用SpringMVC
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="DogStoreApp" version="2.5"> <display-name>Dog Store</display-name> <!-- 集成spring的通用配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/dogstore-security.xml /WEB-INF/dogstore-base.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- SpringMVC前端控制器 --> <servlet> <servlet-name>dogstore</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dogstore</servlet-name> <url-pattern>*.do</url-pattern> <url-pattern>/login.do</url-pattern> </servlet-mapping> <!-- springSecurity核心过滤器配置 --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>login.do</welcome-file> </welcome-file-list> </web-app>
最后,我们还需要Spring Security的自动配置来引用我们新的登录页面。如果你在此时迫不及待想看一下效果的话,我们实际上只是为应用增加了一个新的工作页面。按照上面的流程并输入以下的地址http://localhost:8080/pet/login.do,看看发生了什么。
什么?你是否发现你的请求首先被Spring Security拦截了(被重定向到spring_security_login)并且能够看见那个登录的form?这是因为Spring Security依旧指向了DefaultLoginPageGeneratingFilter生成的默认登录页。一旦你通过了这个过滤器生成的默认登录页,你才能够看到新的自定义登录页。最后一步就是要移除默认页并使用我们的登录form作为登录页。
因此我们要修改dogstore-security.xml文件让login.do能被任何人访问
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http auto-config="true" use-expressions="true"> <intercept-url pattern="/login.do" access="permitAll"/> <intercept-url pattern="/*" access="hasRole(‘ROLE_USER‘)"/> </http> <authentication-manager alias="authenticationManager"> <authentication-provider> <user-service> <user authorities="ROLE_USER" name="guest" password="guest"/> </user-service> </authentication-provider> </authentication-manager> </beans:beans>
注意这个use-expressions="true"这个用法,SpEL使用Spring 表达式语言,可用来定义语法复杂的投票规则
现在我们来登录http://localhost:8080/pet/,返回首页登录界面:
本文出自 “进击的程序猿” 博客,请务必保留此出处http://zangyanan.blog.51cto.com/11610700/1875488
跟我学习Spring Security--在线宠物商店开发(三)
原文:http://zangyanan.blog.51cto.com/11610700/1875488