############################ -- 认证 -- ############################
security-fig:
login-url: /login
login-processing-url: /loginProcess
error-url: /loginFail
logout-url: /signout
swagger-url: /doc
package com.config.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.core.userdetails.UserDetailsService;
/**
* Security fig
*/
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)//开启方法控制注解 @Secured、@PreAuthorize、@PostAuthorize
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value( "${security-fig.login-url}" )
private String loginUrl;
@Value( "${security-fig.login-processing-url}" )
private String loginProcessingUrl;
@Value( "${security-fig.error-url}" )
private String errorUrl;
@Value( "${security-fig.logout-url}" )
private String logoutUrl;
@Autowired
private CustomLogoutService customLogoutService;
@Bean
UserDetailsService customUserService(){
return new CustomLoginService();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.portMapper( )
.http( 80 )
.mapsTo( 443 )
.and()
.authorizeRequests()//登录配置
.antMatchers( "/sys/**" ).permitAll()//允许访问匹配的路径
.antMatchers( "/public/**" ).permitAll()
.antMatchers( "/static/**" ).permitAll()
.antMatchers( "/templates/**" ).permitAll()
.anyRequest().authenticated()//以上配置除外,其它需要认证
.and()
.csrf().disable()//关闭post限制
.formLogin()
.loginPage( loginUrl )//登录页面
.loginProcessingUrl(loginProcessingUrl)//登录action 提交地址
// .defaultSuccessUrl( "/index.html" )//这里指定的是静态页面,必须加后缀,如果不指定,就走路径为“/”的方法
// .failureUrl( "/login?error" )
.failureUrl(errorUrl)//登录失败处理方法
.permitAll()
.and()
.logout()//登出配置
.logoutUrl(logoutUrl)
.deleteCookies("JSESSIONID")//登出清理cookie
.logoutSuccessHandler( customLogoutService )//登出实现类
.permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
//设置静态资源不要拦截
web.ignoring().antMatchers( "/public/**","/static/**","/templates/**");
}
@Autowired
private SecurityAuthenticationProvider provider;//注入我们自己的AuthenticationProvider
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//走默认认证
// auth.userDetailsService( customUserService() ).passwordEncoder( new PasswordConfig() );
//走自定义认证
auth.authenticationProvider(provider);
}
@Autowired
private SecurityAuthenticationProvider provider;//注入我们自己的AuthenticationProvider
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//走默认认证
// auth.userDetailsService( customUserService() ).passwordEncoder( new PasswordConfig() );
//走自定义认证
auth.authenticationProvider(provider);
}
package com.config.security;
import java.util.Collection;
import java.util.Date;
import com.ll.admin.dao.LoginRepository;
import com.ll.admin.domain.Login;
import com.utils.EncryptionUtil;
import com.utils.MD5;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
/**
* 登录逻辑实现
*/
@Component
@Slf4j
public class SecurityAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserDetailsService userDetailService;
@Autowired
private LoginRepository loginRepository;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
WebAuthenticationDetails details =(WebAuthenticationDetails) authentication.getDetails();
String remoteAddress = details.getRemoteAddress();
remoteAddress = "0:0:0:0:0:0:0:1".equals( remoteAddress ) ? "127.0.0.1" : remoteAddress; //访问IP
String userName = authentication.getName(); // 这个获取表单输入中返回的用户名;
String password = authentication.getCredentials().toString(); // 这个是表单中输入的密码;
Login loginData = (Login) userDetailService.loadUserByUsername(userName);
Collection extends GrantedAuthority> authorities = loginData.getAuthorities();
// 构建返回的用户登录成功的token
return new UsernamePasswordAuthenticationToken(loginData, password, authorities);
}
@Override
public boolean supports(Class> authentication) {
// TODO Auto-generated method stub
// 这里直接改成retrun true;表示是支持这个执行
return true;
}
}
package com.config.security;
import com.ll.admin.dao.LoginRepository;
import com.ll.admin.domain.Login;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
/**
* 登出
* 默认被 /signout 请求
*/
@Slf4j
@Component
public class CustomLogoutService implements LogoutSuccessHandler {
@Value( "${server.servlet.context-path}" )
private String contextPath;
@Value( "${security-fig.login-url}" )
private String loginUrl;
@Autowired
private LoginRepository loginRepository;
@Override
public void onLogoutSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication)
throws IOException, ServletException {
//默认被 /signout 请求,这里写登出前要做的事
response.sendRedirect( contextPath + loginUrl );
}
}
@AuthenticationPrincipal UserDetails userDetails 获取当前用户信息
HttpSession session = request.getSession(); SecurityContextImpl ssc = (SecurityContextImpl) session.getAttribute( "SPRING_SECURITY_CONTEXT" ); Authentication authentication = ssc.getAuthentication(); Login details =(Login) authentication.getPrincipal();
package com.config.security;
import com.ll.admin.dto.Msg;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* 登录跳转配置
*/
@Slf4j
@Controller
public class RequestController {
/**
* 成功首页
* @param userDetails
* @param model
* @return
*/
@RequestMapping("/")
public String index (@AuthenticationPrincipal UserDetails userDetails, Model model){
Msg msg = new Msg( "测试标题", "测试内容", "额外信息,只有管理员可以看到!" );
model.addAttribute( "msg",msg );
return "index";
}
/**
* 登录失败返回接口
* @param request
* @param model
* @return
*/
@RequestMapping("/loginFail")
public String loginFail (HttpServletRequest request, Model model){
HttpSession session = request.getSession();
Object badCredentialsException = session.getAttribute( "SPRING_SECURITY_LAST_EXCEPTION" );
String badCredentialsExceptionStr = badCredentialsException.toString();
String msg = badCredentialsExceptionStr.split( ":" )[1];
//错误消息提示
model.addAttribute( "msg",msg);
return "login";
}
}
随笔记录,方便学习
2020-07-03