spring-security 起步

pom.xml

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>

加入过滤器

  1. 选择一:web.xml
  <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>
  1. 选择二:AbstractSecurityWebApplicationInitializer
package cn.johnyu;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {

}

配置安全策略

  1. 使用配置文件,加入security的名称空间(暂时不可用)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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">
<security:http auto-config="true">
    <security:intercept-url pattern="/**" access="ROLE_SPITTER"></security:intercept-url>
</security:http>
</beans>
  1. 使用配置类(继承WebSecurityConfigurerAdapter
package cn.johnyu.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     *用来修改过滤器链
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/images/**");
        web.ignoring().antMatchers("/js/**");
    }

    /**
     *配置UserDetailService,完成"鉴权"
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .passwordEncoder(new StandardPasswordEncoder("53cr3t"));
    }
    /**
     * 修改拦截器,保护请求
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests()
                .antMatchers("/work")
                .hasAuthority("ROLE_READER")
                .antMatchers("/other")
                .hasAnyRole("GUEST","READER")
                .anyRequest().permitAll()
                .and()
                .formLogin()

                .and()
                .exceptionHandling()
                .accessDeniedPage("/forbidden")
                .and()
                .logout()
                .logoutUrl("/logout");
    }
}

关于登录页

  1. 如果没有Override configure(HttpSecurity),则会提供一个默认的登录页(否则没有)
  2. 如果加入.formLogin(),则会找回该登录页
  3. 该页核心内容如下:
<form method="post" action="/WebApp_war_exploded/login">
    <input type="text"  name="username" >
    <input type="password"  name="password">
    <input name="_csrf" type="hidden" value="0386c20f-b2fe-426a-9e0f-d58c0fe254d1"/>
    <button  type="submit">Sign in</button>
</form>
  1. 你可以加入自定义的登录页,方法如下:
.formLogin()
                .loginPage("/login")
                .failureUrl("/login?error=true");

此时,如果有以下控制器

    @RequestMapping("/login")
    public String login(){
        return "login";
    }

则会将页面转向到自定义的页面上。

关于退出

.and()
                .logout()
                .logoutUrl("/logout");

这将指定“/logout”为退出链接,退出后将回到“/login?logout”

关于role不符合

  1. 默认将返回403码
  2. 指定403页面的方法
.and()
                .exceptionHandling()
                .accessDeniedPage("/forbidden")

关于鉴权

  1. 可以使用void configure(AuthenticationManagerBuilder)进行
  2. 可以使用三种方法进行:
@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication();
        auth.inMemoryAuthentication();
        auth.ldapAuthentication();
    }
  1. 无论哪种方式,都将采用hash方式处理密码

使用JDBC进行鉴权

  1. 直接使用(无定制方式)
private DataSource dataSource;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
        .passwordEncoder(new StandardPasswordEncoder("53cr3t"));//这个是必选项
    }
  1. Security默认使用以下表的结构:schema.sql
-- ----------------------------
-- 用户表: username做为唯一字段
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
                         `id` int(8) NOT NULL AUTO_INCREMENT,
                         `username` varchar(20) DEFAULT NULL,
                         `password` varchar(100) DEFAULT NULL,
                         `enabled` tinyint(4) DEFAULT NULL,
                         PRIMARY KEY (`id`)
);

-- ----------------------------
-- 角色表:username外键关联users
-- 注意:它与用户表,存在着间接的 Many To Many 的关系,用户的角色可以来自:直接角色和所属组的角色
-- ----------------------------
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
                               `id` int(11) NOT NULL AUTO_INCREMENT,
                               `username` varchar(20) DEFAULT NULL,
                               `authority` varchar(50) DEFAULT NULL,
                               PRIMARY KEY (`id`)
);

-- ----------------------------
-- 用户组:
-- 注意:它与users存在 Many to Many的关系,但与authorities,是Many To One 的关系
-- ----------------------------
DROP TABLE IF EXISTS `groups`;
CREATE TABLE `groups` (
                          `id` int(11) NOT NULL AUTO_INCREMENT,
                          `groupname` varchar(50) DEFAULT NULL,
                          PRIMARY KEY (`id`)
);

-- ----------------------------
-- users 与 authorites 的一对一的关联表,group_Id外键关联groups表
-- ----------------------------
DROP TABLE IF EXISTS `group_authorities`;
CREATE TABLE `group_authorities` (
                                     `group_Id` int(11) NOT NULL AUTO_INCREMENT,
                                     `authority` varchar(50) DEFAULT NULL,
                                     PRIMARY KEY (`group_Id`)
);

-- ----------------------------
-- 用户 与 用户组 之间的多到多关联关系(username外键关联users表,group_Id外键关联groups表)
-- ----------------------------
DROP TABLE IF EXISTS `group_members`;
CREATE TABLE `group_members` (
                                 `id` int(11) NOT NULL AUTO_INCREMENT,
                                 `username` varchar(20) DEFAULT NULL,
                                 `group_Id` int(11) DEFAULT NULL,
                                 PRIMARY KEY (`id`)
);

初如化的数据:data.sql

-- 密码为123(salt=53cr3t new StandardPasswordEncoder("53cr3t").encode("123"))
insert  into users (username,password,enabled) values('john','97c1e5a28f4d983316d375550e1e28ee50b6d27b5c5a71d6daa4c694227a8d8d94e8e6917ca4ad13',1);
insert  into users (username,password,enabled) values('tom','123',0);
insert  into users (username,password,enabled) values('alice','221a34d7021d75c196b80cbeb0ce53818871ab2a27be7113afc1ee1d08ab157c19cdef4490a06080',1);
-- 必须确保User具有Role
insert into authorities (username,authority) values('john','ROLE_READER');
insert into authorities (username,authority) values('tom','ROLE_READER');
insert into authorities (username,authority) values('alice','ROLE_GUEST');

附:三条核心查询语句:

public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService, MessageSourceAware {
//用于用户身份认证
    public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled from users where username = ?";
//查询用户的角色
    public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority from authorities where username = ?";
//查询用户所属的组的角色
    public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY = "select g.id, g.group_name, ga.authority from groups g, group_members gm, group_authorities ga where gm.username = ? and g.id = ga.group_id and g.id = gm.group_id";
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,227评论 6 342
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,280评论 19 139
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,837评论 1 92
  • Spring Security 学习 Spring Security是一种基于Spring AOP和Servlet...
    ChaLLengerZeng阅读 4,758评论 0 0
  • 10.3 中秋还没到, 兴冲冲的跑过来找你,emm…团圆( ^ω^) 第一次坐卧铺车的心情……(≧∇≦)/ 来到你...
    leaves_C阅读 3,012评论 0 0

友情链接更多精彩内容