본문 바로가기
Dev/[프로젝트] 2022 Spring Boot + JSP

[프로젝트] Spring Boot + JSP 시큐리티 로그인, 권한부여, url 접근 제어,

by javapp 자바앱 2022. 8. 1.
728x90

시큐리티

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)   // @PreAuthorize("isAuthenticated()")  사용
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
	@Autowired
	private UserFailHandler userFailHandler;
	
	@Bean
	public BCryptPasswordEncoder encodPwd() {
		return new BCryptPasswordEncoder();
		
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable();
		http.authorizeRequests()
				.antMatchers("/user*").authenticated()
				.anyRequest().permitAll()
			.and()
				.formLogin()
				.loginPage("/login")
				.loginProcessingUrl("/login")
				.defaultSuccessUrl("/")
				.failureHandler(userFailHandler ) // 실패시 처리할 클래스
			.and()
				.logout()
				.logoutUrl("/logout")
				.logoutSuccessUrl("/")
				.invalidateHttpSession(true);
	}
}

@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)   // @PreAuthorize("isAuthenticated()")  사용

 

//사용 가능해짐

@PreAuthorize("isAuthenticated()") // 인증된 사람만 접근 가능

	@GetMapping("insert")
	@PreAuthorize("isAuthenticated()") // 권한이 있는 사람만 접근 가능
	public String insert() {
		return "/board/insert";
	}

 

 

 


 

 

참고

https://to-dy.tistory.com/86

 

Spring Security - 인증 절차 인터페이스 구현 (1) UserDetailsService, UserDetails

UserDetailsService 인터페이스는 DB에서 유저 정보를 가져오는 역할을 한다. 해당 인터페이스의 메소드에서 DB의 유저 정보를 가져와서 AuthenticationProvider 인터페이스로 유저 정보를 리턴하면, 그 곳

to-dy.tistory.com

 

UserDetails  인터페이스 구현

//User 는 id , password, 권한 뿐이고 UserDetails 은 더 많은 요소로 인증 절차를 할 수 있다.
@NoArgsConstructor
@Data
public class PrincipalDetails  implements UserDetails
{
	private User user;

	public PrincipalDetails(User user) {
		super();
		this.user = user;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		Collection<GrantedAuthority> collect = new ArrayList<GrantedAuthority>();
		collect.add(()->{
			return user.getRole();
		});
		return collect;
	}

	@Override
	public String getPassword() {
		return  user.getPassword();
	}

	@Override
	public String getUsername() {
		// TODO Auto-generated method stub
		return user.getUsername();
	}

	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}
	

}

 

 메소드 명 리턴 타입 설명 
 getAuthorities()  Collection<? extends   GrantedAuthority>  계정이 갖고있는 권한 목록을 리턴한다.
 getPassword()  String  계정의 비밀번호를 리턴한다.
 getUsername()  String  계정의 이름을 리턴한다.
 isAccountNonExpired()  boolean  계정이 만료되지 않았는 지 리턴한다. (true: 만료안됨)
 isAccountNonLocked()  boolean  계정이 잠겨있지 않았는 지 리턴한다. (true: 잠기지 않음)
 isCredentialNonExpired()  boolean  비밀번호가 만료되지 않았는 지 리턴한다. (true: 만료안됨)
 isEnabled()  boolean  계정이 활성화(사용가능)인 지 리턴한다. (true: 활성화)



출처: https://to-dy.tistory.com/86 [todyDev]

 

 

UserDetailsService 인터페이스 구현

@Service
public class PrincipalDetailService implements UserDetailsService 
{
	@Autowired
	private UserRepository userRepository;
	
	// login.jsp 에서 로그인 하면 실행 : /login , post
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		System.out.println("loadUserByUserName");
		User user= userRepository.findByUsername(username); // 해당 값을 DB에서 찾아 user 객체에 저장, 실패시 UserFailHandler
		
		if(user==null) {
			throw new UsernameNotFoundException(username);
		}
	
		PrincipalDetails puser=new PrincipalDetails(user); //시큐리티의 인증 받은 유저로 변환
		System.out.println("puser: "+puser.toString());
		
		return puser;
	}

}

loadUserByUsername ()

DB에서 유저 정보를 불러오는 중요한 메소드

	@PostMapping("/login")
	public String login() {
		return "/user/login";
	}

로그인시 자동실행 loadUserByUsername()

 

     PrincipalDetails puser=new PrincipalDetails(user); UserDetails 클래스를 통해 인증받은 유저로 변환

 

 

 

 

Controller

	@PostMapping("insert") //form , post
	public String insert(Board board,  
			@AuthenticationPrincipal PrincipalDetails principal) 
	{
		boardService.insert(board, principal.getUser());
		return "redirect:/board/list";
	}

public String insert(Board board,  @AuthenticationPrincipal PrincipalDetails principal

{
  boardService.insert(board, principal.getUser()); // PrincipalDetails 유저정보 리턴
  return "redirect:/board/list";
}

 

 

 


 

권한 부여를 통해 지정 경로 접근 제어

public class PrincipalDetails  implements UserDetails
{
	private Member member;

	public PrincipalDetails(Member member) {
		super();
		this.member = member;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		Collection<GrantedAuthority> collect = new ArrayList<GrantedAuthority>();
		collect.add(()->{
			return member.getRole();
		});
		return collect;
	}

collect.add(()->{
   return member.getRole();
});

member의 role 값으로 권한 부여

 

 

db

데이터베이스에 사용자 권한 값 설정

 

 

 

 

@Service
@Transactional
public class PrincipalDetailService implements UserDetailsService 
{
	@Autowired
	private MemberJpaRepository memberJpaRepository;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		Member member= memberJpaRepository.findByName(username); // 해당 값을 DB에서 찾아 user 객체에 저장, 실패시 UserFailHandler
		if(member==null) {
			throw new UsernameNotFoundException(username);
		}
	
		PrincipalDetails puser=new PrincipalDetails(member); //시큐리티의 인증 받은 유저로 변환
		
		return puser;
	}
}

PrincipalDetails puser=new PrincipalDetails(member); //시큐리티의 인증 받은 유저로 변환

 

 

 

 

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)   // @PreAuthorize("isAuthenticated()")  사용
public class SecurityConfig extends WebSecurityConfigurerAdapter // 시큐리티  
{
	@Autowired
	private UserFailHandler userFailHandler;
	@Bean
	public BCryptPasswordEncoder encodePwd() { // 패스워드 암호화 빈 등록
		return new BCryptPasswordEncoder();
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable(); // 의도된 웹 사이트 요청 공격
		http.authorizeRequests()  //권한
				.antMatchers("/user/*").authenticated()    // /user 으로 넘어오는 url 은 인증
				.antMatchers("/tourarea/tourAreaInsert").authenticated()
				.antMatchers("/manage/*").hasAuthority("ADMIN_ROLE")

               ...
	}
}

원하는 url 접근에 대해 role 에 따라 접근 제어 설정

 

.antMatchers("/manage/*").hasAuthority("ADMIN_ROLE")

 

접근 제한 된 페이지

 

설정 후


로그인 후 접근

 

 


 

<sec:authorize> 태그를 사용하여 JSP에서 

사용자의 권한에 따라 접근할 수 있는 메뉴를 동적으로 보여주기

 

 

표현식 설명
hasRole('role') 해당 권한이 있을 경우
hasAnyRole('role1,'role2') 포함된 권한 중 하나라도 있을 경우
isAuthenticated() 권한에 관계없이 로그인 인증을 받은 경우
isFullyAuthenticated() 권한에 관계없이 인증에 성공했고, 자동 로그인이 비활성인 경우
isAnonymous() 권한이 없는 익명의 사용자일 경우
isRememberMe() 자동 로그인을 사용하는 경우
permitAll 모든 경우 출력함
denyAll 모든 경우 출력하지 않음

 

 

댓글