Skip to content

Commit

Permalink
Merge pull request #15 from ecolink-JOIN/feature/login
Browse files Browse the repository at this point in the history
Feat: 로그인 로직 추가
  • Loading branch information
uuujini authored Aug 27, 2024
2 parents 1c09a92 + fc1f14c commit 10b5545
Show file tree
Hide file tree
Showing 41 changed files with 1,069 additions and 161 deletions.
114 changes: 61 additions & 53 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,99 +1,107 @@
buildscript {
ext {
queryDslVersion = "5.0.0"
}
ext {
queryDslVersion = "5.0.0"
}
}

plugins {
id 'java'
id 'org.springframework.boot' version '3.3.2'
id 'io.spring.dependency-management' version '1.1.6'
id 'java'
id 'org.springframework.boot' version '3.3.2'
id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.join'
version = '0.0.1-SNAPSHOT'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
mavenCentral()
}

ext {
set('springCloudVersion', "2022.0.4")
set('springCloudVersion', "2022.0.4")
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.session:spring-session-data-redis'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

//Spring Docs(swagger)
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'

//AWS S3 SDK
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
implementation 'com.amazonaws:aws-java-sdk-s3'

// Utils
implementation 'com.google.guava:guava:28.2-jre'
implementation 'org.apache.commons:commons-lang3:3.9'


//QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.session:spring-session-data-redis'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

//Spring Docs(swagger)
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'

//AWS S3 SDK
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
implementation 'com.amazonaws:aws-java-sdk-s3'

// Utils
implementation 'com.google.guava:guava:28.2-jre'
implementation 'org.apache.commons:commons-lang3:3.9'

// MapStruct
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"
annotationProcessor(
'org.projectlombok:lombok',
'org.projectlombok:lombok-mapstruct-binding:0.1.0'
)


//QueryDSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

tasks.named('bootBuildImage') {
builder = 'paketobuildpacks/builder-jammy-base:latest'
builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}

def querydslDir = "$buildDir/generated/querydsl"

sourceSets {
main.java.srcDirs += [ querydslDir ]
main.java.srcDirs += [querydslDir]
}

tasks.withType(JavaCompile) {
options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
}

clean.doLast {
file(querydslDir).deleteDir()
file(querydslDir).deleteDir()
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.join.core.common.config.security;
package com.join.core.auth.config;

import java.util.List;

Expand All @@ -21,15 +21,26 @@
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import com.join.core.auth.handler.JsonLogoutSuccessHandler;
import com.join.core.auth.handler.OAuth2SuccessHandler;
import com.join.core.auth.service.OAuth2UserLoadingService;

@Configuration
@EnableMethodSecurity
@EnableWebSecurity
public class SecurityConfig {

private static final String AUTHORIZATION_HEADER = "Authorization";
private final OAuth2SuccessHandler oauth2SuccessHandler;
private final OAuth2UserLoadingService oauth2UserLoadingService;
private final JsonLogoutSuccessHandler logoutSuccessHandler;
private final String apiPrefix;

public SecurityConfig(@Value("${api.prefix}") String apiPrefix) {
public SecurityConfig(OAuth2SuccessHandler oauth2SuccessHandler, OAuth2UserLoadingService oauth2UserLoadingService,
JsonLogoutSuccessHandler logoutSuccessHandler, @Value("${api.prefix}") String apiPrefix) {
this.oauth2SuccessHandler = oauth2SuccessHandler;
this.oauth2UserLoadingService = oauth2UserLoadingService;
this.logoutSuccessHandler = logoutSuccessHandler;
this.apiPrefix = apiPrefix;
}

Expand All @@ -38,10 +49,13 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
http.cors(cors -> cors.configurationSource(websiteConfigurationSource()))
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
// .oauth2Login(oauth ->
// oauth.authorizationEndpoint(authorization -> authorization.baseUri(apiPrefix + "/oauth2/authorization"))
// .redirectionEndpoint(redirection -> redirection.baseUri(apiPrefix + "/oauth2/code")))
.logout(logout -> logout.logoutUrl(apiPrefix + "/logout"))
.oauth2Login(oauth ->
oauth.authorizationEndpoint(authorization -> authorization.baseUri(apiPrefix + "/oauth2/authorization"))
.redirectionEndpoint(redirection -> redirection.baseUri(apiPrefix + "/oauth2/code"))
.userInfoEndpoint(userInfo -> userInfo.userService(oauth2UserLoadingService))
.successHandler(oauth2SuccessHandler))
.logout(logout -> logout.logoutUrl(apiPrefix + "/logout")
.logoutSuccessHandler(logoutSuccessHandler))
.headers(headers ->
headers.addHeaderWriter(
new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));
Expand Down Expand Up @@ -70,8 +84,8 @@ static HttpSessionIdResolver httpSessionIdResolver() {
static RoleHierarchy roleHierarchy() {
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("""
ROLE_ADMIN > ROLE_MANAGER
ROLE_MANAGER > ROLE_USER
ROLE_ADMIN > ROLE_USER
ROLE_USER > ROLE_GUEST
""");
return hierarchy;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.join.core.user.constant;
package com.join.core.auth.constant;

import static java.util.stream.Collectors.*;

Expand All @@ -19,13 +19,14 @@ public OAuth2Attributes extract(String attributeKey, Map<String, Object> attribu
KAKAO("kakao") {
@Override
public OAuth2Attributes extract(String attributeKey, Map<String, Object> attributes) {
String keyAttribute = (String)attributes.get(attributeKey);
Map<String, Object> kakaoAccount = (Map<String, Object>)attributes.get("kakao_account");
Map<String, Object> kakaoProfile = (Map<String, Object>)kakaoAccount.get("profile");

var builder = OAuth2Attributes.builder()
.attributes(attributes)
.userType(this)
.attributeKey(attributeKey)
.platform(this)
.attributeKey(keyAttribute)
.email((String)kakaoAccount.get("email"))
.name((String)kakaoProfile.get("nickname"));

Expand All @@ -43,7 +44,7 @@ public OAuth2Attributes extract(String attributeKey, Map<String, Object> attribu
public OAuth2Attributes extract(String attributeKey, Map<String, Object> attributes) {
return OAuth2Attributes.builder()
.attributes(attributes)
.userType(this)
.platform(this)
.attributeKey(attributeKey)
.build();
}
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/com/join/core/auth/domain/AuthenticationToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.join.core.auth.domain;

import java.util.Collection;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

public class AuthenticationToken extends AbstractAuthenticationToken {

private final UserPrincipal principal;

private AuthenticationToken(UserPrincipal principal, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
}

public AuthenticationToken(UserInfo.SigIn sigIn) {
this(UserPrincipal.of(sigIn), sigIn.getAuthorities());
}

@Override
public Object getCredentials() {
return null;
}

@Override
public Object getPrincipal() {
return this.principal;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof AuthenticationToken that))
return false;
if (!super.equals(o))
return false;

return principal.equals(that.principal);
}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + principal.hashCode();
return result;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.join.core.user.domain;
package com.join.core.auth.domain;

import com.join.core.user.constant.RoleType;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
Expand All @@ -24,10 +24,29 @@ public class Role {

@NotNull
@Enumerated(EnumType.STRING)
private RoleType roleType;
private Type type;

public Role(RoleType roleType) {
this.roleType = roleType;
@Getter
public enum Type {
NO_PROFILE("NO_PROFILE"),
USER("ROLE_USER"),
ADMIN("ROLE_ADMIN"),
GUEST("ROLE_GUEST");

private final String authority;

Type(String authority) {
this.authority = authority;
}

}

public Role(Type type) {
this.type = type;
}

SimpleGrantedAuthority toGrantedAuthority() {
return new SimpleGrantedAuthority(this.type.getAuthority());
}

}
Loading

0 comments on commit 10b5545

Please sign in to comment.