为认证添加JSON支持
This commit is contained in:
parent
837b311eb4
commit
2b2f434917
5
pom.xml
5
pom.xml
@ -79,11 +79,6 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
|
@ -0,0 +1,39 @@
|
||||
package com.codesdream.ase.component.permission;
|
||||
|
||||
import com.codesdream.ase.component.datamanager.JSONParameter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
// 认证用户访问无权限资源
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ASEAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
@Resource
|
||||
private JSONParameter jsonParameter;
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
|
||||
throws IOException, ServletException {
|
||||
log.info("ASEAccessDeniedHandler Found!");
|
||||
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/javascript;charset=utf-8");
|
||||
UserLoginCheckerRespond checkerRespond = new UserLoginCheckerRespond();
|
||||
checkerRespond.setLoginStatus(true);
|
||||
checkerRespond.setUserExist(true);
|
||||
checkerRespond.setRespondInformation("Authenticated user has no access to this resource");
|
||||
|
||||
// 对匿名用户返回
|
||||
response.getWriter().print(jsonParameter.getJSONString(checkerRespond));
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.codesdream.ase.component.permission;
|
||||
|
||||
import com.codesdream.ase.component.datamanager.JSONParameter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
// 匿名用户访问无权限资源
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ASEAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
@Resource
|
||||
private JSONParameter jsonParameter;
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
|
||||
throws IOException, ServletException {
|
||||
log.info("ASEAuthenticationEntryPoint Found!");
|
||||
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/javascript;charset=utf-8");
|
||||
UserLoginCheckerRespond checkerRespond = new UserLoginCheckerRespond();
|
||||
checkerRespond.setLoginStatus(false);
|
||||
checkerRespond.setUserExist(false);
|
||||
checkerRespond.setUserBanned(true);
|
||||
checkerRespond.setRespondInformation("Anonymous user has no access to this resource");
|
||||
|
||||
// 对匿名用户返回
|
||||
response.getWriter().print(jsonParameter.getJSONString(checkerRespond));
|
||||
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.codesdream.ase.component.permission;
|
||||
|
||||
import com.codesdream.ase.component.datamanager.JSONParameter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
@ -13,6 +14,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
// 认证失败返回
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ASEAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
|
||||
|
||||
@ -23,10 +26,14 @@ public class ASEAuthenticationFailureHandler extends SimpleUrlAuthenticationFail
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
logger.info("ASEAuthenticationSuccessHandler Login Fail!");
|
||||
log.info("ASEAuthenticationSuccessHandler Login Fail!");
|
||||
UserLoginCheckerRespond respond = new UserLoginCheckerRespond();
|
||||
respond.setUserExist(false);
|
||||
respond.setLoginStatus(false);
|
||||
respond.setUserBanned(true);
|
||||
respond.setRespondInformation("Authentication Failed");
|
||||
|
||||
// 填充response对象
|
||||
response.getWriter().write(jsonParameter.getJSONString(respond));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.codesdream.ase.component.permission;
|
||||
|
||||
import com.codesdream.ase.component.datamanager.JSONParameter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -10,7 +11,10 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
|
||||
// 认证成功返回
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
|
||||
@Resource
|
||||
@ -20,10 +24,12 @@ public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthentica
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
logger.info("ASEAuthenticationSuccessHandler Login Success!");
|
||||
log.info("ASEAuthenticationSuccessHandler Login Success!");
|
||||
UserLoginCheckerRespond respond = new UserLoginCheckerRespond();
|
||||
respond.setUserExist(true);
|
||||
respond.setLoginStatus(true);
|
||||
respond.setUserExist(authentication.isAuthenticated());
|
||||
respond.setLoginStatus(authentication.isAuthenticated());
|
||||
// 填充response对象
|
||||
response.getWriter().write(jsonParameter.getJSONString(respond));
|
||||
/* response.sendRedirect("/home");*/
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ public class ASESecurityAuthenticationProvider implements AuthenticationProvider
|
||||
String password = passwordEncoder.encode(authentication.getCredentials().toString());
|
||||
// 判断用户是否存在
|
||||
UserDetails userInfo = userDetailsService.loadUserByUsername(username);
|
||||
|
||||
log.info(String.format("SecurityAuthentication: %s %s", username, password));
|
||||
|
||||
if (userInfo == null) {
|
||||
throw new UsernameNotFoundException("User IS Not Existing");
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
package com.codesdream.ase.component.permission;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ASEUnauthorizedEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
|
||||
if(isAjaxRequest(request)){
|
||||
log.info("IS Ajax Request.");
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,authException.getMessage());
|
||||
}else{
|
||||
log.info("IS NOT Ajax Request.");
|
||||
response.sendRedirect("/login");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAjaxRequest(HttpServletRequest request) {
|
||||
String ajaxFlag = request.getHeader("X-Requested-With");
|
||||
return "XMLHttpRequest".equals(ajaxFlag);
|
||||
}
|
||||
}
|
@ -2,48 +2,45 @@ package com.codesdream.ase.component.permission;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.codesdream.ase.component.datamanager.JSONParameter;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.util.TextEscapeUtils;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
|
||||
// 登录验证过滤器
|
||||
public class ASEUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
// 常量
|
||||
public static final String SPRING_SECURITY_RESTFUL_USERNAME_KEY = "username";
|
||||
public static final String SPRING_SECURITY_RESTFUL_PASSWORD_KEY = "password";
|
||||
public static final String SPRING_SECURITY_RESTFUL_LOGIN_URL = "/login";
|
||||
|
||||
private String usernameParameter = SPRING_SECURITY_RESTFUL_USERNAME_KEY;
|
||||
private String passwordParameter = SPRING_SECURITY_RESTFUL_PASSWORD_KEY;
|
||||
private boolean postOnly = true;
|
||||
@Slf4j
|
||||
public class ASEUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||
|
||||
@Resource
|
||||
private JSONParameter jsonParameter;
|
||||
|
||||
protected ASEUsernamePasswordAuthenticationFilter() {
|
||||
super(new AntPathRequestMatcher(SPRING_SECURITY_RESTFUL_LOGIN_URL, "POST"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, IOException, ServletException {
|
||||
// 检查提交方式
|
||||
if (postOnly && !request.getMethod().equals("POST")) {
|
||||
throw new AuthenticationServiceException(
|
||||
"Authentication Method NOT Supported: " + request.getMethod());
|
||||
}
|
||||
throws AuthenticationException {
|
||||
// 判断是否为JSON格式的数据
|
||||
log.info(String.format("Content Type: %s", request.getContentType()));
|
||||
if(request.getContentType().equals("application/x-www-form-urlencoded; charset=UTF-8")) {
|
||||
|
||||
UserLoginChecker checker = jsonParameter.getJavaObjectByRequest(request, UserLoginChecker.class);
|
||||
if(!checker.getCheckType().equals("UserLoginChecker"))
|
||||
if (!checker.getCheckType().equals("From"))
|
||||
throw new AuthenticationServiceException("Invalid Checker Type");
|
||||
|
||||
String username = checker.getUsername();
|
||||
@ -55,11 +52,17 @@ public class ASEUsernamePasswordAuthenticationFilter extends AbstractAuthenticat
|
||||
// 去除首尾两端的空白字符
|
||||
username = username.trim();
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
|
||||
username, password);
|
||||
UsernamePasswordAuthenticationToken authRequest =
|
||||
new UsernamePasswordAuthenticationToken(username, password);
|
||||
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
log.info(String.format("User Authentication: %s %s.", username, password));
|
||||
|
||||
setDetails(request, authRequest);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
else{
|
||||
return super.attemptAuthentication(request, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import lombok.EqualsAndHashCode;
|
||||
public class UserLoginCheckerRespond extends RespondJSONBaseObject {
|
||||
boolean userExist = false;
|
||||
boolean loginStatus = false;
|
||||
boolean userBanned = false;
|
||||
String respondInformation = "";
|
||||
|
||||
public UserLoginCheckerRespond(){
|
||||
super("success");
|
||||
|
@ -1,14 +1,16 @@
|
||||
package com.codesdream.ase.configure;
|
||||
|
||||
import com.codesdream.ase.component.permission.ASEPasswordEncoder;
|
||||
import com.codesdream.ase.component.permission.ASESecurityAuthenticationProvider;
|
||||
import com.codesdream.ase.component.permission.*;
|
||||
import com.codesdream.ase.service.ASEUserDetailsService;
|
||||
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.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.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@ -29,18 +31,33 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Resource
|
||||
ASESecurityAuthenticationProvider aseSecurityAuthenticationProvider;
|
||||
|
||||
@Resource
|
||||
ASEAuthenticationSuccessHandler successHandler;
|
||||
|
||||
@Resource
|
||||
ASEAuthenticationFailureHandler failureHandler;
|
||||
|
||||
@Resource
|
||||
ASEAuthenticationEntryPoint authenticationEntryPoint;
|
||||
|
||||
@Resource
|
||||
ASEAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
http
|
||||
.authorizeRequests()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.csrf().disable().formLogin()
|
||||
.and()
|
||||
.formLogin().loginPage("/login")
|
||||
.permitAll().defaultSuccessUrl("/home").permitAll()
|
||||
.and()
|
||||
.csrf().disable()
|
||||
.logout().permitAll();
|
||||
|
||||
http.exceptionHandling()
|
||||
.authenticationEntryPoint(authenticationEntryPoint)
|
||||
.accessDeniedHandler(accessDeniedHandler);
|
||||
|
||||
// 替换掉原有的UsernamePasswordAuthenticationFilter
|
||||
http.addFilterBefore(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,4 +79,18 @@ public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
"/error/**",
|
||||
"/login/**");
|
||||
}
|
||||
|
||||
//注册自定义的UsernamePasswordAuthenticationFilter
|
||||
@Bean
|
||||
ASEUsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception {
|
||||
ASEUsernamePasswordAuthenticationFilter filter = new ASEUsernamePasswordAuthenticationFilter();
|
||||
filter.setAuthenticationSuccessHandler(successHandler);
|
||||
filter.setAuthenticationFailureHandler(failureHandler);
|
||||
filter.setRequiresAuthenticationRequestMatcher(
|
||||
new AntPathRequestMatcher("/login/process", "POST"));
|
||||
|
||||
|
||||
filter.setAuthenticationManager(authenticationManagerBean());
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
package com.codesdream.ase.configure;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Spring 框架全局配置类
|
||||
|
@ -18,3 +18,5 @@ spring.datasource.password=codedreampasswd
|
||||
|
||||
server.error.whitelabel.enabled=false
|
||||
|
||||
logging.level.org.springframework.security=DEBUG
|
||||
|
||||
|
@ -146,16 +146,34 @@ function callback_decorator(callback){
|
||||
return callback;
|
||||
}
|
||||
|
||||
function ase_serialize_object(form)
|
||||
{
|
||||
const o = {};
|
||||
const a = form.serializeArray();
|
||||
$.each(a, function() {
|
||||
if (o[this.name] !== undefined) {
|
||||
if (!o[this.name].push) {
|
||||
o[this.name] = [o[this.name]];
|
||||
}
|
||||
o[this.name].push(this.value || '');
|
||||
} else {
|
||||
o[this.name] = this.value || '';
|
||||
}
|
||||
});
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
// 快速以post方式提交表单
|
||||
function ase_form_post(url ,id, callback){
|
||||
const form = ase_tag_getter("form", id);
|
||||
callback = callback_decorator(callback);
|
||||
|
||||
const form_object = ase_serialize_object(ase_tag_getter("form", id));
|
||||
form_object.checkType = "From";
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
url: url ,
|
||||
data: form.serialize(),
|
||||
data: JSON.stringify(form_object),
|
||||
success: callback.success,
|
||||
error : callback.error,
|
||||
});
|
||||
|
@ -16,7 +16,7 @@ function notify_check() {
|
||||
}
|
||||
|
||||
function login() {
|
||||
ase_form_post("/login","login-form", {
|
||||
ase_form_post("/login/process","login-form", {
|
||||
success : function (result) {
|
||||
console.log(result);
|
||||
},
|
||||
|
@ -17,7 +17,7 @@
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">登录</h4>
|
||||
</div>
|
||||
<form id="login-form" action="/login" method="post">
|
||||
<form id="login-form" action="/login/process" method="post">
|
||||
<div class="card-body">
|
||||
<div id="username-group" class="form-group">
|
||||
<label for="username">学号</label>
|
||||
|
Loading…
Reference in New Issue
Block a user