spring-boot-learning-spring Security
SpringSecurity的简单原理:
一旦启用了Spring Security,Spring IoC容器就会为你创建一个名称为springSecurityFilterChain 的Spring Bean。
它的类型为FilterChainProxy,事实上它也实现了Filter接口, 只是它是一个特殊的拦截器。在Spring Security 操作的
过程中它会提供Servlet 过滤器DelegatingFilterProxy , 这个过滤器会通过Spring Web IoC 容器去获取
Spring Security所自动创建的FilterChainProxy 对象,这个对象上存在一个拦截器列表( List ),列表上存在用户验证
的拦截器、跨站点请求伪造等拦截器,这样它就可以提供多种拦截功能。于是焦点又落到了FilterChainProxy 对象上,通过它
还可以注册Filter ,也就是允许注册自定义的Filter 来实现对应的拦截逻辑,以满足不同的需要。当然,Spring Security
也实现了大部分常用的安全功能,并提供了相应的机制来简化开发者的工作,所以大部分情况下并不需要自定义开发,使用它提供
的机制即可
怎么开启spring security
web工程可以使用@EnableWebSecurity来驱动spring security启动。
非web工程,使用@EnableGlobalAuthentication
实际上,@EnableWebSecurity这个注解上面已经标注了@EnableGlobalAuthentication注解
WebSecurityConfigurerAdapter中的方法:
/**
* WebSecurityConfigurerAdapter虽然实现了接口WebSecurityConfigurer
* 但是这个实现是空实现来的,不存在任何配置
* AuthenticationManagerBuilder定义用户,密码,角色。默认不会创建任何用户和
* 密码==有登录页面没有登录用户
*/
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> { /**
*配置用户签名服务,user-details机制,可以给用户赋予角色
*
* @param auth 签名管理构造器,用于构建用户权限控制
* @throws Exception
*/
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
this.disableLocalConfigureAuthenticationBldr = true;
} /**
* 用于配置Filter链
* @param web
* @throws Exception
*/
public void configure(WebSecurity web) throws Exception {
} /**
* 用于配置拦截保护请求,比如什么请求放行,什么请求验证
* HttpSecurity参数方法:指定用户和角色对对应URL的访问权限。
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug("Using default configure(HttpSecurity). " +
"If subclassed this will potentially override subclass configure(HttpSecurity).");
((HttpSecurity)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)
http.authorizeRequests().anyRequest()).authenticated().and())
.formLogin().and()).httpBasic();
}
使用内存签名服务
package com.quan.security; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
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;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; /**
* springSecurit默认没有任何用户配置,springboot中,如果没有,自动生成一个
* 名称为user,密码通过随机生成,可以在日志中知道。
* 自定义用户签名服务=密码:内存签名服务,数据库签名服务,自定义签名服务
*/
@SpringBootApplication
//@EnableWebSecurity
public class SpringbootsecurityApplication extends WebSecurityConfigurerAdapter { /**
* spring5后都要求使用密码编码器。
* 11建立密码编码器实例BCryptPasswordEncoder,实现接口PasswordEncoder
* 是单向不可逆的密码加密方式。
* 22inMemoryAuthentication(),这个方法将返回内存保存用户信息的管理配置InMemoryUserDetailsManagerConfigurer
* 启用内存缓存机制保存用户信息
* 33passwordEncoder,设置密码编码器
* 44withUser 返回UserDetailsBuilder用户详情构造器对象
* 用于配置用户信息
* 55password,设置密码,密码设置必须是经过密码编码器加密后的字符串,使用密码登录的时候是用加密前
* 66赋予角色类型。之后通过角色赋予权限
* 备注:role方法是对authorities方法的简写,role给的角色名称实际上还会加上ROLE_,如下面的源码展示
* 77and方法表示连接,开启另一个用户的注册。
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String p1 = passwordEncoder.encode("hllhll");
String p2 = passwordEncoder.encode("HLLHLL"); //这里是更便捷的方式
// InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> userConfig = auth.inMemoryAuthentication().passwordEncoder(passwordEncoder);
// //因为使用了authorities,所以必须加入前缀
// userConfig.withUser("quanadmin")
// .password(p1).authorities("ROLE_USER","ROLE_ADMIN");
//
// userConfig.withUser("quanuser")
// .password(p2).authorities("ROLE_USER"); auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("quanadmin")
.password(p1)
.roles("USER","ADMIN")
.and()
.withUser("quanuser")
.password(p2)
.roles("USER");
} /**InMenoryUserDetailsManagerConfigurer方法
* public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception {
* return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer());
* }
*
*/ /**role方法
* public User.UserBuilder roles(String... roles) {
* List<GrantedAuthority> authorities = new ArrayList(roles.length);
* String[] var3 = roles;
* int var4 = roles.length;
*
* for(int var5 = 0; var5 < var4; ++var5) {
* String role = var3[var5];
* Assert.isTrue(!role.startsWith("ROLE_"), () -> {
* return role + " cannot start with ROLE_ (it is automatically added)";
* });
* authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
* }
*
* return this.authorities((Collection)authorities);
* }
* @param
*/ public static void main(String[] args) {
SpringApplication.run(SpringbootsecurityApplication.class, args);
} }
使用数据库定义用户认证
@SpringBootApplication
//@EnableWebSecurity
public class SpringbootsecurityApplication extends WebSecurityConfigurerAdapter { @Autowired
private DataSource dataSource = null;
String pwdQ = "select user_name,pwd,available from t_user where user_name = ?";
String roleQ = "select u.user_name,r.role_name from t_user as u, t_user_role as ur,t_role as r " +
"where u.id = ur.user_id and r.id = ur.role_id AND u.user_name = ?"; /**
* 11新建数据库和数据库表以及加入相关数据
* 22通过@Autowire注入数据源,注入数据源之前要加入依赖
* 这里使用jdbc数据源,和mysql-connection-java驱动
* 33重写方法configure(AuthenticationManagerBuilder auth)
* 44准备查询语句 如上面的pwdQ和roleQ
* 55使用AuthenticationManagerBuilder的jdbcAuthentication方法,
* 开启jdbc的方式进行验证服务
* 66passwordEncoder设置密码的编码器。
* 注意:虽然每一次的密码的编码出来的字符串都不一样,但是数据库里面
* 只要存了一次编码之后的字符串,都可以解密
* 77usersByUsernameQuery通过查询语句返回的user pwd 布尔值,可以对用户进行验证了
* 其中布尔值就是available标明用户是否失效
* 88authoritiesByUsernameQuery通过查询语句知道用户的角色,spring security可以根据
* 查询的结果赋予权限。
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println(passwordEncoder.encode("123456"));
//虽然每一次的密码的编码出来的字符串都不一样,但是数据库里面只要存了一次编码之后的字符串,都可以解密
auth.jdbcAuthentication()
.passwordEncoder(passwordEncoder)
.dataSource(dataSource)
.usersByUsernameQuery(pwdQ)
.authoritiesByUsernameQuery(roleQ);
} public static void main(String[] args) {
SpringApplication.run(SpringbootsecurityApplication.class, args);
}
}
限制请求:
/**
* 限制请求
* 默认WebSecurityConfigurerAdapte有默认的实现configure(HttpSecurity http)
* 默认只要认证成功,做什么都可以
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); //authorizeRequests()限定只对签名成功的用户请求
//anyRequest() 限定所有请求
//authenticated()对所有签名成功的用户允许方法
//.formLogin()代表使用默认登录界面
//httpBasic()启动http基础认知
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
自定义:
@Override
protected void configure(HttpSecurity http) throws Exception {
//authorizeRequests表示设置哪些需要签名的请求,并可以将不同请求权限赋予不同角色
http.authorizeRequests()
//antMatchers配置请求路径,hasAnyRole指定角色(默认加前缀ROLE_),两个觉得哪些角色可以访问哪些路径
.antMatchers("/user/welcome").hasAnyRole("ADMIN","USER")
.antMatchers("/admin/**").hasAnyRole("ADMIN")
//anyRequest没有限制任何请求,permitAll表示没有设置访问权限的路径允许全部访问
.anyRequest().permitAll()
//允许匿名访问
.and().anonymous() .and().formLogin() .and().httpBasic();
}
EL
/**
* 使用spring表达式设置, spring EL
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() .antMatchers("/user/welcome").access("hasRole('USER') or hasRole('ADMIN')") .antMatchers("/admin/w1").access("hasAuthority('ROLE_ADMIN') && isFullyAuthenticated()") .antMatchers("/admin/w1").access("hasAuthority('ROLE_ADMIN')")
.and().rememberMe() .and().formLogin() .and().httpBasic();
}
------------恢复内容开始------------
SpringSecurity的简单原理:
一旦启用了Spring Security,Spring IoC容器就会为你创建一个名称为springSecurityFilterChain 的Spring Bean。
它的类型为FilterChainProxy,事实上它也实现了Filter接口, 只是它是一个特殊的拦截器。在Spring Security 操作的
过程中它会提供Servlet 过滤器DelegatingFilterProxy , 这个过滤器会通过Spring Web IoC 容器去获取
Spring Security所自动创建的FilterChainProxy 对象,这个对象上存在一个拦截器列表( List ),列表上存在用户验证
的拦截器、跨站点请求伪造等拦截器,这样它就可以提供多种拦截功能。于是焦点又落到了FilterChainProxy 对象上,通过它
还可以注册Filter ,也就是允许注册自定义的Filter 来实现对应的拦截逻辑,以满足不同的需要。当然,Spring Security
也实现了大部分常用的安全功能,并提供了相应的机制来简化开发者的工作,所以大部分情况下并不需要自定义开发,使用它提供
的机制即可
怎么开启spring security
web工程可以使用@EnableWebSecurity来驱动spring security启动。
非web工程,使用@EnableGlobalAuthentication
实际上,@EnableWebSecurity这个注解上面已经标注了@EnableGlobalAuthentication注解
WebSecurityConfigurerAdapter中的方法:
/**
* WebSecurityConfigurerAdapter虽然实现了接口WebSecurityConfigurer
* 但是这个实现是空实现来的,不存在任何配置
* AuthenticationManagerBuilder定义用户,密码,角色。默认不会创建任何用户和
* 密码==有登录页面没有登录用户
*/
public abstract class WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> { /**
*配置用户签名服务,user-details机制,可以给用户赋予角色
*
* @param auth 签名管理构造器,用于构建用户权限控制
* @throws Exception
*/
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
this.disableLocalConfigureAuthenticationBldr = true;
} /**
* 用于配置Filter链
* @param web
* @throws Exception
*/
public void configure(WebSecurity web) throws Exception {
} /**
* 用于配置拦截保护请求,比如什么请求放行,什么请求验证
* HttpSecurity参数方法:指定用户和角色对对应URL的访问权限。
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
this.logger.debug("Using default configure(HttpSecurity). " +
"If subclassed this will potentially override subclass configure(HttpSecurity).");
((HttpSecurity)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)
http.authorizeRequests().anyRequest()).authenticated().and())
.formLogin().and()).httpBasic();
}
使用内存签名服务
package com.quan.security; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
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;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; /**
* springSecurit默认没有任何用户配置,springboot中,如果没有,自动生成一个
* 名称为user,密码通过随机生成,可以在日志中知道。
* 自定义用户签名服务=密码:内存签名服务,数据库签名服务,自定义签名服务
*/
@SpringBootApplication
//@EnableWebSecurity
public class SpringbootsecurityApplication extends WebSecurityConfigurerAdapter { /**
* spring5后都要求使用密码编码器。
* 11建立密码编码器实例BCryptPasswordEncoder,实现接口PasswordEncoder
* 是单向不可逆的密码加密方式。
* 22inMemoryAuthentication(),这个方法将返回内存保存用户信息的管理配置InMemoryUserDetailsManagerConfigurer
* 启用内存缓存机制保存用户信息
* 33passwordEncoder,设置密码编码器
* 44withUser 返回UserDetailsBuilder用户详情构造器对象
* 用于配置用户信息
* 55password,设置密码,密码设置必须是经过密码编码器加密后的字符串,使用密码登录的时候是用加密前
* 66赋予角色类型。之后通过角色赋予权限
* 备注:role方法是对authorities方法的简写,role给的角色名称实际上还会加上ROLE_,如下面的源码展示
* 77and方法表示连接,开启另一个用户的注册。
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String p1 = passwordEncoder.encode("hllhll");
String p2 = passwordEncoder.encode("HLLHLL"); //这里是更便捷的方式
// InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> userConfig = auth.inMemoryAuthentication().passwordEncoder(passwordEncoder);
// //因为使用了authorities,所以必须加入前缀
// userConfig.withUser("quanadmin")
// .password(p1).authorities("ROLE_USER","ROLE_ADMIN");
//
// userConfig.withUser("quanuser")
// .password(p2).authorities("ROLE_USER"); auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("quanadmin")
.password(p1)
.roles("USER","ADMIN")
.and()
.withUser("quanuser")
.password(p2)
.roles("USER");
} /**InMenoryUserDetailsManagerConfigurer方法
* public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception {
* return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer());
* }
*
*/ /**role方法
* public User.UserBuilder roles(String... roles) {
* List<GrantedAuthority> authorities = new ArrayList(roles.length);
* String[] var3 = roles;
* int var4 = roles.length;
*
* for(int var5 = 0; var5 < var4; ++var5) {
* String role = var3[var5];
* Assert.isTrue(!role.startsWith("ROLE_"), () -> {
* return role + " cannot start with ROLE_ (it is automatically added)";
* });
* authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
* }
*
* return this.authorities((Collection)authorities);
* }
* @param
*/ public static void main(String[] args) {
SpringApplication.run(SpringbootsecurityApplication.class, args);
} }
使用数据库定义用户认证
@SpringBootApplication
//@EnableWebSecurity
public class SpringbootsecurityApplication extends WebSecurityConfigurerAdapter { @Autowired
private DataSource dataSource = null;
String pwdQ = "select user_name,pwd,available from t_user where user_name = ?";
String roleQ = "select u.user_name,r.role_name from t_user as u, t_user_role as ur,t_role as r " +
"where u.id = ur.user_id and r.id = ur.role_id AND u.user_name = ?"; /**
* 11新建数据库和数据库表以及加入相关数据
* 22通过@Autowire注入数据源,注入数据源之前要加入依赖
* 这里使用jdbc数据源,和mysql-connection-java驱动
* 33重写方法configure(AuthenticationManagerBuilder auth)
* 44准备查询语句 如上面的pwdQ和roleQ
* 55使用AuthenticationManagerBuilder的jdbcAuthentication方法,
* 开启jdbc的方式进行验证服务
* 66passwordEncoder设置密码的编码器。
* 注意:虽然每一次的密码的编码出来的字符串都不一样,但是数据库里面
* 只要存了一次编码之后的字符串,都可以解密
* 77usersByUsernameQuery通过查询语句返回的user pwd 布尔值,可以对用户进行验证了
* 其中布尔值就是available标明用户是否失效
* 88authoritiesByUsernameQuery通过查询语句知道用户的角色,spring security可以根据
* 查询的结果赋予权限。
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println(passwordEncoder.encode("123456"));
//虽然每一次的密码的编码出来的字符串都不一样,但是数据库里面只要存了一次编码之后的字符串,都可以解密
auth.jdbcAuthentication()
.passwordEncoder(passwordEncoder)
.dataSource(dataSource)
.usersByUsernameQuery(pwdQ)
.authoritiesByUsernameQuery(roleQ);
} public static void main(String[] args) {
SpringApplication.run(SpringbootsecurityApplication.class, args);
}
}
限制请求:
/**
* 限制请求
* 默认WebSecurityConfigurerAdapte有默认的实现configure(HttpSecurity http)
* 默认只要认证成功,做什么都可以
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity)."); //authorizeRequests()限定只对签名成功的用户请求
//anyRequest() 限定所有请求
//authenticated()对所有签名成功的用户允许方法
//.formLogin()代表使用默认登录界面
//httpBasic()启动http基础认知
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
自定义:
@Override
protected void configure(HttpSecurity http) throws Exception {
//authorizeRequests表示设置哪些需要签名的请求,并可以将不同请求权限赋予不同角色
http.authorizeRequests()
//antMatchers配置请求路径,hasAnyRole指定角色(默认加前缀ROLE_),两个觉得哪些角色可以访问哪些路径
.antMatchers("/user/welcome").hasAnyRole("ADMIN","USER")
.antMatchers("/admin/**").hasAnyRole("ADMIN")
//anyRequest没有限制任何请求,permitAll表示没有设置访问权限的路径允许全部访问
.anyRequest().permitAll()
//允许匿名访问
.and().anonymous() .and().formLogin() .and().httpBasic();
}
EL
/**
* 使用spring表达式设置, spring EL
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() .antMatchers("/user/welcome").access("hasRole('USER') or hasRole('ADMIN')") .antMatchers("/admin/w1").access("hasAuthority('ROLE_ADMIN') && isFullyAuthenticated()") .antMatchers("/admin/w1").access("hasAuthority('ROLE_ADMIN')")
.and().rememberMe() .and().formLogin() .and().httpBasic();
}
强制使用https;
/**
* springSecurit默认没有任何用户配置,springboot中,如果没有,自动生成一个
* 名称为user,密码通过随机生成,可以在日志中知道。
* 自定义用户签名服务=密码:内存签名服务,数据库签名服务,自定义签名服务
*/
@SpringBootApplication
@EnableWebSecurity
public class SpringbootsecurityApplication extends WebSecurityConfigurerAdapter { /**
* 强制使用https
* 实际环境当中,信息需要谨慎的额进行保护,通过https进行加密。
* requiresChannel方法说明使用通道,requiresSecure表示https请求
* requiresInSecure取消安全请求机制
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//设置/admin/**这个通道使用安全渠道,限定为https请求
http.requiresChannel().antMatchers("/admin/**").requiresSecure()
//设置/user/**这个通道不使用安全渠道
.and().requiresChannel().antMatchers("/user/**").requiresInsecure()
.and().authorizeRequests().antMatchers("/admin/**").hasAnyRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER","ADMIN");
} //
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String p1 = passwordEncoder.encode("hllhll");
String p2 = passwordEncoder.encode("HLLHLL"); auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("quanadmin")
.password(p1)
.roles("USER","ADMIN")
.and()
.withUser("quanuser")
.password(p2)
.roles("USER");
}
跨站点访问请
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="./commit" method="post">
<p>
名;<input id="name" name="name" type="text" value=""/>
</p>
<p>
描述;<input id="describe" name="describe" type="text" value=""/>
</p>
<p>
<input type="submit" value="提交">
</p>
<input type="hidden" id="${_csrf.parameterName}" name="${_csfr.parameterName}" value="${_csrf.token}"/>
</form>
</body>
</html>
<%--隐藏的是JSTL表达式
_csrf对象是Spring提供的,启动CSRF攻击的安全认知功能后,
SpringSecurity机制会生成对应的CSRF参数,他的属性parameterName
代表的是名称,token代表的是token值。都会放在form隐藏域当中。
提交的时候,提交到服务器后端,ss会进行验证这个token参数是否有效
--%>
用户认证功能:
1自定义登录界面;
@SpringBootApplication
@EnableWebSecurity
public class Springbootweb17Application extends WebSecurityConfigurerAdapter { /**
* 自定义登录页面:登录请求连接+记住我
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 访问/admin下的时候需要ADMIN权限
http.authorizeRequests().antMatchers("/admin/**").access("hasRole('ADMIN')")
//开启remember me功能设置token的有效期间,浏览器会使用cookie remember-me-key保存,MD5加密保存
.and().rememberMe().tokenValiditySeconds(86400).key("remember-me-key")
//开启 HTTP Batic功能
.and().httpBasic()
//一旦签名通过后,所有的都可以访问,注意如果不是admin那就不是全部
.and().authorizeRequests().antMatchers("/**").permitAll()
//登入路径,默认登录成功跳转路径为/admin/welcome 会在webmvc配置类进行对应的登录页面设置
.and().formLogin().loginPage("/login/page").defaultSuccessUrl("/login/welcome")
//登出路径,登出成功默认跳转路径/welcome
.and().logout().logoutUrl("/logout/page").logoutSuccessUrl("/logout/welcome");
http.httpBasic().realmName("my-basic-name");
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String p1 = passwordEncoder.encode("hllhll");
String p2 = passwordEncoder.encode("HLLHLL"); auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("quanadmin")
.password(p1)
.roles("USER","ADMIN")
.and()
.withUser("quanuser")
.password(p2)
.roles("USER");
} public static void main(String[] args) {
SpringApplication.run(Springbootweb17Application.class, args);
} }
进行URL和jsp的映射关系配置;
@Configuration
public class WebConfig implements WebMvcConfigurer { /**
* 增加映射关系
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//访问/login/page 映射为页面login.jsp
registry.addViewController("login/page").setViewName("login");
//访问/logout 映射为logout.jsp
// registry.addViewController("/logout").setViewName("logout");
//登录成功会跳转到/login/welcome 这个URL,所以这里做一个映射到logint_welcome.jsp
registry.addViewController("/login/welcome").setViewName("login_welcome");
//选择登出的时候回跳转到/logout/welcome,所以这里映射到logout_welcome.jsp
registry.addViewController("/logout/welcome").setViewName("logout_welcome");
}
}
login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html>
<head>
<title>欢迎来到傻逼无</title>
</head>
<%--注意:表单里面的参数名称必须是username 和password --%>
<body>
<form action="/login/page" method="post">
<p>名称:<input id="username" name="username" type="text" value=""></p>
<p>密码:<input id="password" name="password" type="password" value=""></p>
<p>记住我:<input id="remember_me" name="remember_me" type="checkbox" value=""></p>
<input type="submit" value="登录"/>
<%-- 表单中加入隐藏的对应参数就能避免CSRF攻击了,--%>
<input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</body>
</html>
login_welcome.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
加油,L2
<form action="/logout/page" method="post">
<input type="submit" value="登出">
<input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<%--登出的时候,也是需要验证csrf的,如果没有这个是退出错误的。--%>
</form>
</body>
</html>
logout_welcome.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登出</title>
</head>
<body>
<h2>您已经登出系统</h2>
</body>
</html>
spring-boot-learning-spring Security的更多相关文章
- spring boot+freemarker+spring security标签权限判断
spring boot+freemarker+spring security标签权限判断 SpringBoot+SpringSecurity+Freemarker项目中在页面上使用security标签 ...
- 一:Spring Boot、Spring Cloud
上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇.其实我们在这条路上已经走了一年多,从16年初到现在. ...
- spring boot与spring mvc的区别是什么?
Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面 ...
- spring boot与spring mvc的区别
Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面 ...
- 基于Spring Boot和Spring Cloud实现微服务架构学习
转载自:http://blog.csdn.net/enweitech/article/details/52582918 看了几周Spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习感 ...
- 基于Spring Boot和Spring Cloud实现微服务架构学习--转
原文地址:http://blog.csdn.net/enweitech/article/details/52582918 看了几周spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习 ...
- 基于Spring Boot和Spring Cloud实现微服务架构
官网的技术导读真的描述的很详细,虽然对于我们看英文很费劲,但如果英文不是很差,请选择沉下心去读,你一定能收获好多.我的学习是先从Spring boot开始的,然后接触到微服务架构,当然,这一切最大的启 ...
- Spring Boot中Spring data注解的使用
文章目录 Spring Data Annotations @Transactional @NoRepositoryBean @Param @Id @Transient @CreatedBy, @Las ...
- Spring Boot 与 Spring MVC到底有什么区别
前言 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向 ...
- 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践
由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...
随机推荐
- windev中字符串分隔符的选择以及Contains使用技巧
字符串分隔符,理论上可以使用任意符号,但作为数据保存,建议只使用以下三种: 1.:分号 2.TAB制表符 3.CR换行符 主要有以下几个原因: 1.组织架构组件,获得的组织路径,使用TAB键分隔,TA ...
- 安装python和pycharm,以及常见安装问题
目录 安装python 输入第一个python程序 安装python文本编辑器pycharm 执行main.py文件出现的问题 python编码规范 python是当前很常用的一门语言了,和Java, ...
- 调用WCF服务的几种方式
首先发布了一个名为PersonService的WCF服务.服务契约如下: [ServiceContract] public interface IPersonService { ...
- c# TextBox只能输入数字的处理方法(完整版各种情况考虑在内,可根据需求灵活修改)
//选择文本框的事件窗口,找到按键输入的方法KeyPress,双击建立新的方法. /// <summary> /// textBox只能输入数字的处理方法 /// </summary ...
- python面试_总结02_代码题
- 代码题 1.创建一个函数,接收一个字符串参数,判断其做为Python标识符是否合法. 具体要求: 如果合法则输出 True,否则输出 False. 如果该字符串与Python内置的关键字,或Bif ...
- numpy.random模块用法小结
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9751471.html 1.np.random.random()函数参数 np.random.r ...
- Write Combining Buffer
现代CPU使用了很多技术来降低对内存存取数据的延时,因为CPU执行的速度实在是太快了,在从内存存取数据的约120ns中,可以执行数百条指令. 其中多级的缓存架构就是为了减少这种延时,来提高CPU的利用 ...
- Chapter06 数组(Array)
目录 Chapter06 数组 6.1 数组的认识 6.2 数组的使用 使用方式1 - 动态初始化 使用方式2 - 动态初始化 使用方法3 - 静态初始化 6.3 数组使用的注意事项和细节 6.4 数 ...
- JZ-017-树的子结构
树的子结构 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 题目链接: 树的子结构 代码 /** * 标题:树的子结构 * 题目描述 * 输入两棵 ...
- 矩池云上安装yolov4 darknet教程
这里我是用PyTorch 1.8.1来安装的 拉取仓库 官方仓库 git clone https://github.com/AlexeyAB/darknet 镜像仓库 git clone https: ...