시큐리티
@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";
}
참고
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 값으로 권한 부여
데이터베이스에 사용자 권한 값 설정
@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 | 모든 경우 출력하지 않음 |
'Dev > [프로젝트] 2022 Spring Boot + JSP' 카테고리의 다른 글
[프로젝트] Spring Boot + JSP를 이용한 함께 부산 여행할 사람을 구하는 웹 사이트-이슈 (0) | 2022.08.01 |
---|---|
[프로젝트] Spring Boot + JSP를 이용한 함께 부산 여행할 사람을 구하는 웹 사이트-4-JSP 페이지 (0) | 2022.07.31 |
[프로젝트] Spring Boot + JSP를 이용한 함께 부산 여행할 사람을 구하는 웹 사이트-3-JPA (0) | 2022.07.31 |
[프로젝트] Spring Boot + JSP를 이용한 함께 부산 여행할 사람을 구하는 웹 사이트-2-요구분석, 설계 (0) | 2022.07.30 |
[프로젝트] Spring Boot + JSP를 이용한 함께 부산 여행할 사람을 구하는 웹 사이트-1-기획 (0) | 2022.07.30 |
댓글