package com.imooc.security.browser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
public PasswordEncoder passwordEncoder() {
//这里如果是自己编写的加密 则调用自己的类 方法有编码和解码验证方法
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//认证
.loginPage("/imooc-signIn.html")//设置登录页面
.loginProcessingUrl("/authentication/form")//遇到该请求则进行user password认证
// http.httpBasic()
.and()
.authorizeRequests()//授权
//当访问这个路径的时候不需要身份认证 除了它其他的是需要身份认证
.antMatchers("/imooc-signIn.html").permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
package com.imooc.security.browser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class MyUserDetailsService implements UserDetailsService {
private Logger logger = LoggerFactory.getLogger(MyUserDetailsService.class);
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.info("登录用户名:"+username);
//根据用户名查找用户信息
//根据查找到的用户信息判断用户是否被冻结
String password = passwordEncoder.encode("123456");
logger.info("数据库密码是"+password);
return new User(username, password,//encode方法是加密的时候用的
true,true,true,true,//依次代表 可用,没过期,密码没过期,没有被锁定为false
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h2>标准登录页面</h2>
<h3>表单登录</h3>
<form action="/authentication/form" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><button type="submit">登录</button></td>
</tr>
</table>
</form>
</body>
</html>
代码结构图。启动测试结果:
到这里继续跟着我的节奏走:请看图:
跟着我的节奏继续走,我保证不烦死你,很简单.....终极配置。。。。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h1>demo登录页</h1>
</body>
</html>
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/imooc-demo?useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username = root
spring.datasource.password = 123456
spring.session.store-type = none
#security.basic.enabled = false
server.port = 8060
imooc.security.browser.loginPage=/demo-signIn.html
package com.imooc.security.core;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import com.imooc.security.core.properties.SecurityProperties;
/**
* 使我们写的properties生效
* @author 35-pxiaodong
*
*/
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}
package com.imooc.security.core.properties;
public class BrowserProperties {
//设定默认值如果没有指定loginPage则访问该页面
private String loginPage = "/imooc-singIn.html";
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
}
package com.imooc.security.core.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="imooc.security")
public class SecurityProperties {
private BrowserProperties browsers = new BrowserProperties();
public BrowserProperties getBrowsers() {
return browsers;
}
public void setBrowsers(BrowserProperties browsers) {
this.browsers = browsers;
}
}
package com.imooc.security.browser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.imooc.security.core.properties.SecurityProperties;
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private SecurityProperties securityProperties;
@Bean
public PasswordEncoder passwordEncoder() {
//这里如果是自己编写的加密 则调用自己的类 方法有编码和解码验证方法
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()//认证
.loginPage("/authentication/require")//设置登录页面
.loginProcessingUrl("/authentication/form")//遇到该请求则进行user password认证
// http.httpBasic()
.and()
.authorizeRequests()//授权
//当访问这个路径的时候不需要身份认证 除了它其他的是需要身份认证
.antMatchers("/authentication/require"
,securityProperties.getBrowsers().getLoginPage()).permitAll()
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
}
package com.imooc.security.browser;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.imooc.security.browser.support.SimpleResponse;
import com.imooc.security.core.properties.SecurityProperties;
@RestController
public class BrowserSecurityController {
private Logger logger = LoggerFactory.getLogger(getClass());
private RequestCache requestCache = new HttpSessionRequestCache();
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Autowired
private SecurityProperties securityProperties;
/**
* 当需要身份验证时跳转到这里
* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping("/authentication/require")
@ResponseStatus(code=HttpStatus.UNAUTHORIZED)//返回401状态码
public SimpleResponse requireAuthentication(HttpServletRequest request
,HttpServletResponse response) throws IOException {
//保存的之前的请求(引发跳转的请求)拿出来
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest != null) {
//引发跳转的url
String targetUrl = savedRequest.getRedirectUrl();
logger.info("引发跳转的请求是:"+targetUrl);
if (StringUtils.endsWithIgnoreCase(targetUrl, "html")) {
redirectStrategy.sendRedirect(request, response, securityProperties.getBrowsers().getLoginPage());
}
}
return new SimpleResponse("访问的服务需要身份认证,请引导用户到登录页");
}
}
package com.imooc.security.browser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class MyUserDetailsService implements UserDetailsService {
private Logger logger = LoggerFactory.getLogger(MyUserDetailsService.class);
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.info("登录用户名:"+username);
//根据用户名查找用户信息
//根据查找到的用户信息判断用户是否被冻结
String password = passwordEncoder.encode("123456");
logger.info("数据库密码是"+password);
return new User(username, password,//encode方法是加密的时候用的
true,true,true,true,//依次代表 可用,没过期,密码没过期,没有被锁定为false
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
/**
*
*/
package com.imooc.security.browser.support;
/**
* @author 35-pxiaodong
*
*/
public class SimpleResponse {
public SimpleResponse(Object content) {
this.content=content;
}
private Object content;
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h2>标准登录页面</h2>
<h3>表单登录</h3>
<form action="/authentication/form" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><button type="submit">登录</button></td>
</tr>
</table>
</form>
</body>
</html>
喘口气启动demo,看测试结果吧,其实我还没测呢,不知道预期结果怎么样,3,2,1。。。。。
访问该路径看来是没问题:
然后访问一个html试试吧,好紧张,啾啾~~
啊啊啊啊啊啊 报错了 贴上错误,让后让我解决:
机智的我立马找到了错误:
之前贴过的代码我就不改了,不然你们不会出错也就看不下去了。更改后继续访问html:
ok! here the movie is over thaks for your searching and watching .
bye !bye!