在学习spring secuity之前我们先构建一个spring mvc的web程序,以后的spring secuity就在这个web程序基础上去构建。
- 加入依赖
我们使用maven构建项目,我们加入了springmvc
和servlet
相关的依赖,并且加入了jetty插件,可以不使用外部容器的情况下去运行启动项目,依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>springmvc-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.3.v20170317</version>
<configuration>
<httpConnector>
<port>8001</port>
</httpConnector>
//配置contextPath为/
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
- 首先定义系统启动根类
配置的@EnableWebMvc注解的类需要继承WebMvcConfigurerAdapter
,来做一下回调配置(比如说自己定义的类型转换器,自己定义的拦截器等),详细了解可以点击查看@EnableWebMvc
的源码备注
@EnableWebMvc
@ComponentScan("com.zhihao.miao.mvc")
public class WebAppConfig extends WebMvcConfigurerAdapter {
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
//配置默认的DefaultServletHttpRequestHandler(静态资源默认使用的servlet),DefaultServletHttpRequestHandler是HttpRequestHandler的默认实现,
configurer.enable();
}
}
- 其他的一些配置
/**
* 系统启动类,配置url过滤的url
*/
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
//以我的理解就是以WebAppConfig来创建spring 容器上下文
return new Class<?>[]{WebAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/*"};
}
}
- 定义自己的Controller
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello spring mvc web";
}
@GetMapping("/home")
public String home(){
return "home spring mvc web";
}
@GetMapping("/admin")
public String admin(){
return "admin spring mvc web";
}
}
- 测试
访问下面三个接口,都可以访问,
http://localhost:8001/hello
http://localhost:8001/home
http://localhost:8001/admin
- url的组成
这边说明一下url地址的一些组成,比如说http://127.0.0.1:8081/home
,其可以看成http[s]://[host]:[port][request url][?queryString]
,而request url = [context path][servlet path][path info]
,url路径除了context path
和servlet path
之外就是path_info
了,我们这边没有配置context path
和servlet path
。
修改一下Controller,
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(HttpServletRequest req){
System.out.println("==================");
System.out.println(" req.getRequestURI(): " + req.getRequestURI());
System.out.println(" req.getContextPath(): " + req.getContextPath());
System.out.println(" req.getServletPath(): " + req.getServletPath());
System.out.println(" req.getPathInfo(): " + req.getPathInfo());
System.out.println("==================");
return "hello spring mvc web";
}
@GetMapping("/home")
public String home(){
return "home spring mvc web";
}
@GetMapping("/admin")
public String admin(){
return "admin spring mvc web";
}
}
控制台打印:
==================
req.getRequestURI(): /hello
req.getContextPath():
req.getServletPath():
req.getPathInfo(): /hello
==================
- 我们修改pom文件的jetty插件的
context path
如下,
<build>
<finalName>springmvc-web</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.3.v20170317</version>
<configuration>
<httpConnector>
<port>8001</port>
</httpConnector>
<webApp>
<!--修改contextPath>
<contextPath>/web</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
此时访问的url地址就改成了:
http://localhost:8001/web/hello
控制台打印:
==================
req.getRequestURI(): /web/hello
req.getContextPath(): /web
req.getServletPath():
req.getPathInfo(): /hello
==================
- 我们再去修改
servlet path
,修改配置类中
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
//以我的理解就是以WebAppConfig来创建spring 容器上下文
return new Class<?>[]{WebAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
/**
* url mapping 通常有三种配置方式
*
* 1: /*
* 2: /aaa/*, /aaa/bbb/*
* 3: *.do, *.action
*
* 第一种配置方式 servlet Path 为空
* 第二种配置方式 servlet Path /aaa, /aaa/bbb/
* 第三种配置方式servlet Path /aaa/bbb.do, /aaa/bbb.action
*
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/v1/*","/v2/*"};
}
}
此时访问路径:
http://localhost:8001/web/v1/hello
控制台打印:
==================
req.getRequestURI(): /web/v1/hello
req.getContextPath(): /web
req.getServletPath(): /v1
req.getPathInfo(): /hello
==================
或者:
http://localhost:8001/web/v2/hello
控制台打印:
==================
req.getRequestURI(): /web/v2/hello
req.getContextPath(): /web
req.getServletPath(): /v2
req.getPathInfo(): /hello
==================
讲到这边一个基于spring web构建的web程序已经搭建成功,并且可以进行访问了,我们发现我们应用暴露的url地址不管是谁都可以访问,这样是不安全的,我们希望其得到一些权限认证,不同的人员认证之后才可以访问具体的资源。而spring secuity就是为了解决这个问题的,当然spring secuity框架能为我们做的事情不仅如此。
Spring Security
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security是一个强大的且高度可定制化的身份认证和访问控制框架。是一个基于Spring之上的一个提供安全解决方案的框架
- 特征
- 多种认证方式HTTP BASIC,HTTP Digest(HTTP摘要认证),X.509,LDAP。Form-based(HTTP表单认证),OpenID,CAS
- 多种权限验证,支持基于URL的权限验证,方法的权限验证等
- 多种安全领域的解决方案,XSS,XSRF,CORS,session管理,单点登录(CAS),OAuth等等。
- 强大的可扩展性,可配置性
- 基于官方Java Config(注解)和xml的配置方式
- 官方集成springboot,大大简化了spring security的开发难度。