Springsecurityデフォルトの例
61269 ワード
ページごとにアクセス権を決定する例を作りたいです.
SampleController.java
package org.conan.controller;
import java.util.ArrayList;
import java.util.Arrays;
import org.conan.domain.SampleDTO;
import org.conan.domain.SampleDTOList;
import org.conan.domain.TodoDTO;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import lombok.extern.log4j.Log4j;
@Controller // 컨트롤러라는 걸 알리기 위한 선언
@Log4j // 콘솔창에 log로 찍기 위해 선언하는 것
@RequestMapping("/sample/*") // 주소창에 /sample로 들어오는 건 다 처리
public class SampleController {
// @InitBinder
// public void initBinder(WebDataBinder binder) {
// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(dateFormat,false));
// }
@GetMapping("/ex01")
public String ex01(SampleDTO dto) {
log.info("" + dto); // 콘솔창에 띄우기 위한 출력문
return "ex01";
}
@GetMapping("/ex02")
public String ex02(@RequestParam("name") String name, @RequestParam("age") int age) {
log.info("name : " + name);
log.info("age : "+ age);
return "ex02";
}
@GetMapping("/ex02List")
public String ex02List(@RequestParam("ids") ArrayList<String> ids) {
log.info("ids : " + ids);
return "ex02List";
}
@GetMapping("/ex02Array")
public String ex02Array(@RequestParam("ids") String[] ids) {
log.info("array ids : " + Arrays.toString(ids));
return "ex02Array";
}
@GetMapping("/ex02Bean")
public String ex02Bean(SampleDTOList list) {
log.info("list dtos : " + list);
return "ex02Bean";
}
@GetMapping("/ex03")
public String ex03(TodoDTO todo) {
log.info("todo : " + todo);
return "ex03";
}
@GetMapping("/ex04")
public String ex04(SampleDTO dto, @ModelAttribute("page")int page) {
// 강제로 전달받은 파라미터를 모델에 담아서 타입에 관계없이 전달
log.info("dto : " + dto);
log.info("age : " + page);
return "/sample/ex04";
}
@GetMapping("/ex05")
public void ex05() {
log.info("ex05........................");
}
@GetMapping("/ex06")
public @ResponseBody SampleDTO ex06() {
log.info("ex06........................");
SampleDTO dto = new SampleDTO();
dto.setAge(10);
dto.setName("conan");
return dto;
}
@GetMapping("/ex07")
public ResponseEntity <String> ex07(){
log.info("ex07....");
String msg = String.format("{\"name\":\"conan\"}");
HttpHeaders header = new HttpHeaders();
header.add("Content-Type", "application/json;charset=UTF-8");
return new ResponseEntity<>(msg,header,HttpStatus.OK);
}
@GetMapping("/exUpload")
public void exUpload() {
log.info("exUpload......");
}
@PostMapping("/exUploadPost")
public void exUploadPost(ArrayList<MultipartFile> files) {
for(MultipartFile file:files) {
log.info("name : " + file.getOriginalFilename());
log.info("size : " + file.getSize());
}
}
@GetMapping("/all")
public void doAll() {
log.info("누구나 접근 가능");
}
@GetMapping("/member")
public void doMember() {
log.info("로그인 한 회원들만 접근 가능");
}
@GetMapping("/admin")
public void doAdmin() {
log.info("관리자들만 접근 가능");
}
}
jspを作成し、ページの移動を確認した後
security-context.xmlに追加
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:form-login />
</security:http>
<security:authentication-manager></security:authentication-manager>
これを追加すると、/sample/memberでアクセスする場合springsecurityで自動的に作成されたログインが使用可能になりました
でも私はだめです.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_4_0.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!-- 파일 업로드 -->
<multipart-config>
<location>c:\\upload</location> <!-- 업로드되는 파일 저장 공간 -->
<max-file-size>20971520</max-file-size> <!-- 업로드되는 파일의 최대 크기 -->
<max-request-size>41943040</max-request-size> <!-- 한 번에 올릴 수 있는 최대 크기 -->
<file-size-threshold>20971520</file-size-threshold> <!-- 특정 사이즈의 메모리 사용 -->
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
<!-- spring security -->
<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>
</web-app>
securityを読み込むコンテンツを追加security-contextxmlを読み込むことができますそれでいいxmlに追加
では.
security-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll" />
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:form-login/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
メンバー、メンバーとしてしかログインできません{noop}が存在しない場合は空の値に入ります(これは符号化機能です)
一時的な機能と見なす
したがって、メンバーとしてログインしてadminページにアクセスしようとすると、
このように出てくるはずです.
adminを追加します
security-context.xmlフルコード
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll" />
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')" />
<security:form-login/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_MEMBER, ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
これによりadminはmemberページにもアクセスできます.メンバーはadminページにアクセスできません
errorページのパブリッシュ
CommonController.java
CommonControllerの作成
package org.conan.controller;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
public class CommonController {
@GetMapping("/accessError")
public void accessDenied(Authentication auth, Model model) {
log.info("access Denied : "+auth);
model.addAttribute("msg", "Access Denied");
}
}
次にaccessError.jspの作成
accessError.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Access Denied Page</h1>
<h2><c:out value="${SPRING_SECURITY_403_EXCEPTION.getMessage() }"/></h2>
<h2><c:out value="${msg }"/></h2>
</body>
</html>
security-context.xml
コードの追加
すべてのコード
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/sample/all" access="permitAll" />
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')" />
<security:form-login/>
<security:access-denied-handler error-page="/accessError"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_MEMBER, ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
エラーが発生した場合は、contextから読み込んでコントローラに送信します.コントローラから作成したエラーページに送信
その他のエラーページの作成
次に
せいぞう
CustomAccessDeniedHandler.java
package org.conan.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import lombok.extern.log4j.Log4j;
@Log4j
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException{
log.error("Access Denied Handler");
log.error("Redirect");
response.sendRedirect("/accessError");
}
}
security-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security-5.2.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/sample/all" access="permitAll" />
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')" />
<security:form-login login-page="/customLogin"/>
<!-- 내가 만든 로그인 페이지(/customLogin) 를 쓰겠다고 하는거 -->
<security:access-denied-handler ref="customAccessDenied"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_MEMBER, ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="customAccessDenied" class="org.conan.security.CustomAccessDeniedHandler"></bean>
</beans>
作成したログインページにアクセス
CustomAccessDeniedHandler.java
package org.conan.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import lombok.extern.log4j.Log4j;
@Log4j
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException{
log.error("Access Denied Handler");
log.error("Redirect");
response.sendRedirect("/accessError");
}
}
CommonController.java
package org.conan.controller;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
public class CommonController {
@GetMapping("/accessError")
public void accessDenied(Authentication auth, Model model) {
log.info("access Denied : "+auth);
model.addAttribute("msg", "Access Denied");
}
@GetMapping("/customLogin")
public void loginInput(String error, String logout, Model model) {
log.info("error : "+error);
log.info("logout : "+error);
if(error != null) {
model.addAttribute("error", "Login Error Check Your Account");
}
if(logout != null) {
model.addAttribute("logout", "LogOut!");
}
}
}
Loginページでcsrfトークンが作成されていることを確認します
インスペクタ確認を開くと、アプリケーション-Cookieをクリアして再確認します.
csrfの値が異なることがわかります
非常に順調である
Reference
この問題について(Springsecurityデフォルトの例), 我々は、より多くの情報をここで見つけました https://velog.io/@tkaqhcjstk/spring-security-기본-예제テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol