对于 web 安全的控制,以前接触使用过 Shiro。
刚好最近在学习整理 Spring 相关的技术,就学习一下 Spring Security。
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.
Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements.
看了下官方的文档 5.0.0.RELEASE doc,
案例依赖于 gradle,一直以来使用的是 maven。
就直接按照 Spring Security入门程序示例 作为入门。
$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
$ mvn -v
Apache Maven 3.3.9
完整代码地址,如有帮助不妨给个 Star。
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── ryo
│ │ └── spring
│ │ └── security
│ │ └── hello
│ │ └── controller
│ │ └── HelloWorldController.java
│ ├── resources
│ │ ├── application-mvc.xml
│ │ ├── application-security.xml
│ │ └── application.xml
│ └── webapp
│ └── WEB-INF
│ ├── pages
│ │ ├── admin.jsp
│ │ └── hello.jsp
│ └── web.xml
引入指定的 jar 和插件。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-securityartifactId>
<groupId>com.ryogroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>spring-security-helloartifactId>
<packaging>warpackaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platformgroupId>
<artifactId>platform-bomartifactId>
<version>2.0.8.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-coreartifactId>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-configartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>8080port>
<path>/path>
<uriEncoding>UTF-8uriEncoding>
configuration>
plugin>
plugins>
build>
project>
两个 jsp 页面,内容如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<head>
<meta charset="utf-8">
head>
<body>
<h1>标题: ${title}h1>
<h1>消息 : ${message}h1>
<c:if test="${pageContext.request.userPrincipal.name != null}">
<h2>欢迎: ${pageContext.request.userPrincipal.name}
| <a href="j_spring_security_logout " />" > Logouta>h2>
c:if>
body>
html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
head>
<body>
<h1>标题:${title}h1>
<h1>消息:${message}h1>
body>
html>
用于指定 web 项目相关的配置,内容如下:
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Archetype Created Web Applicationdisplay-name>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:application.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:application-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>springSecurityFilterChainfilter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy
filter-class>
filter>
<filter-mapping>
<filter-name>springSecurityFilterChainfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
spring 配置文件,引入了 application-mvc.xml
和 application-security.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="application-mvc.xml"/>
<import resource="application-security.xml"/>
beans>
spring mvc 的配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.ryo.spring.security.hello.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
beans>
spring security 的配置:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd">
<http auto-config="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_USER')" />
http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="ryo" password="123456" authorities="ROLE_USER" />
user-service>
authentication-provider>
authentication-manager>
beans:beans>
简单的页面控制类:
package com.ryo.spring.security.hello.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/")
public class HelloWorldController {
/**
* 返回 hello 视图
* @return
*/
@RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is welcome page!");
model.setViewName("hello");
return model;
}
/**
* 返回 admin 视图
* @return
*/
@RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page!");
model.setViewName("admin");
return model;
}
}
直接运行 插件 tomcat7:run
启动服务,或者手动部署到 tomcat,此处不再赘述。
启动日志如下:
[INFO] Scanning for projects...
...
[INFO] Running war on http://localhost:8080/
...
[INFO] Mapped "{[/admin**],methods=[GET]}" onto public org.springframework.web.servlet.ModelAndView com.ryo.spring.security.hello.controller.HelloWorldController.adminPage()
[INFO] Mapped "{[/ || /welcome**],methods=[GET]}" onto public org.springframework.web.servlet.ModelAndView com.ryo.spring.security.hello.controller.HelloWorldController.welcomePage()
...
信息: Starting ProtocolHandler ["http-bio-8080"]
直接浏览器访问 http://localhost:8080/,首页内容如下:
标题:Spring Security Hello World
消息:This is welcome page!
如果我们尝试访问 http://localhost:8080/admin,会进入登录页面。
用户名密码和我们 application-security.xml
文件中配置一致。
一、输入错误信息
页面内容如下:
Your login attempt was not successful, try again.
Reason: Bad credentials
二、输入正确信息
标题: Spring Security Hello World
消息 : This is protected page!
欢迎: ryo | Logout
好,到这里入门就介绍完毕。
后续会继续学习,并记录下笔记。