-
spring boot swagger settingIT/spring 2021. 2. 5. 12:13
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Value("${project.properties.swagger-host}")
private String swaggerHost;
@Autowired
ServerProperties serverProperties;
@Autowired
private TypeResolver typeResolver;
@Bean
public Docket api(TypeResolver typeResolver) {
ResolvedRecursiveType resolvedRecursiveType = new ResolvedRecursiveType(Integer.class, null);
Optional<ResolvedType> typeInt = Optional.of(resolvedRecursiveType);
resolvedRecursiveType = new ResolvedRecursiveType(String.class, null);
Optional<ResolvedType> typeString = Optional.of(resolvedRecursiveType);
AllowableListValues osTypeAllowableList = new AllowableListValues(Stream.of(OsType.values()).map(it -> it.name()).collect(Collectors.toList()), "string");
Parameter cponId = new Parameter("X-cponId", "폰 아이디", "test-cponId", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter serialNo = new Parameter("X-serialNo", "디바이스 고유 번호", "test-serialNo", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter cponModel = new Parameter("X-cponModel", "폰 모델명", "test-cponModel", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter osTypeCd = new Parameter("X-osTypeCd", "폰 OS 타입", "OST001", false, false, new ModelRef("string"), typeString, osTypeAllowableList, "header" , null, false, new ArrayList<>());
Parameter osVersion = new Parameter("X-osVer", "폰 OS 버전", "test-cponModel", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter pkgNm = new Parameter("X-pkgNm", "어플 패키지명", "test-pkgNm", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter pkgVersion = new Parameter("X-pkgVer", "어플 VERSION", "test-pkgVer", false, false, new ModelRef("string"), typeString, null, "header" , null, false, new ArrayList<>());
Parameter userSeq = new Parameter("X-userSeq", "서버 회원 고유 아이디", "1", false, false, new ModelRef("int"), typeInt, null, "header" , null, false, new ArrayList<>());
return new Docket(DocumentationType.SWAGGER_2)
.host(swaggerHost)
.apiInfo(apiInfo())
.ignoredParameterTypes(MedicineHeader.class)
.select()
.apis(RequestHandlerSelectors.basePackage("com.test.t.controller.api"))
.paths(PathSelectors.any())
.build()
.additionalModels(typeResolver.resolve(Msg.class, Error.class))
.globalOperationParameters(Arrays.asList(cponId, serialNo, cponModel, osTypeCd, osVersion, pkgNm, pkgVersion, userSeq))
.globalResponseMessage(RequestMethod.GET, getCustomizedResponseMessages())
.globalResponseMessage(RequestMethod.POST, getCustomizedResponseMessages())
.globalResponseMessage(RequestMethod.DELETE, getCustomizedResponseMessages())
.globalResponseMessage(RequestMethod.PUT, getCustomizedResponseMessages())
.useDefaultResponseMessages(false);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("medicine Brain")
.description("medicine documents")
.build();
}
private List<ResponseMessage> getCustomizedResponseMessages(){
ModelRef modelRef = new ModelRef(Error.class.getSimpleName());
List<ResponseMessage> responseMessages = new ArrayList<>();
responseMessages.add(new ResponseMessageBuilder().code(500).message("Server has crashed!! and Error").responseModel(modelRef).build());
return responseMessages;
}
}@Configuration
@Import({CommonWebMvcConfigurerAdapter.class})
@EnableWebMvc
@EnableConfigurationProperties(ProjectProperties.class)
@EnableScheduling
@EnableTransactionManagement
public class WebMvcConfigurerAdapter extends org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter {
@Value("${project.properties.angular-path}")
private String angularPath;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/swagger/v2/api-docs", "/v2/api-docs").setKeepQueryParams(true);
registry.addRedirectViewController("/swagger/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/swagger/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/swagger/swagger-resources", "/swagger-resources");
}
//리소스 패스 설정
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**") .addResourceLocations("/WEB-INF/resources/");
registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/swagger/**") .addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/assets/**") .addResourceLocations(angularPath+"/assets/");
registry.addResourceHandler("/favicon.ico") .addResourceLocations(angularPath+"/assets/img/favicon/favicon.ico");
registry.addResourceHandler("/*.html") .addResourceLocations(angularPath+"/");
registry.addResourceHandler("/*.map") .addResourceLocations(angularPath+"/");
registry.addResourceHandler("/*.js") .addResourceLocations(angularPath+"/");
}
}
@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableWebSecurity
public class WebSecurityConfigurerAdapter extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/resources/**",
"/webjars/**",
"/assets/**",
"/*.js",
"/*.map",
"/favicon.ico",
API_PATH+"/**"
);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
List<AccessDecisionVoter<? extends Object>> accessDecisionVoters = new ArrayList<>();
RoleVoter roleVoter = new RoleVoter();
accessDecisionVoters.add(roleVoter);
AffirmativeBased affirmativeBased = new AffirmativeBased(accessDecisionVoters);
affirmativeBased.setAllowIfAllAbstainDecisions(false);
FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
filterSecurityInterceptor.setAuthenticationManager(authenticationManagerBean());
filterSecurityInterceptor.setAccessDecisionManager(affirmativeBased);filterSecurityInterceptor.setSecurityMetadataSource(new FilterInvocationSecurityMetadataSource());
http
.anonymous()
.and()
.csrf()
.ignoringAntMatchers(LOGOUT_URL)
.csrfTokenRepository(csrfTokenRepository())
.and()
.authorizeRequests()
.anyRequest().hasAnyAuthority()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.formLogin()
.loginPage(LOGIN_PAGE) //로그인 페이지
.loginProcessingUrl(LOGIN_PROCESSING_URL) //login-processing-url 로그인 페이지 form action에 입력할 주소 지정
.usernameParameter(USERNAME_PARAMETER)
.passwordParameter(USERPWD_PARAMETER)
.defaultSuccessUrl(DEFAULT_SUCCESS_URL) //성공시 이동될 페이지
.failureHandler(authenticationFailureHandler())
.successHandler(new AuthenticationSuccessHandler())
.permitAll()
.and()
.logout()
.deleteCookies(REMEMBER_ME_COOKE_NAME)
.deleteCookies("JSESSIONID")
.deleteCookies(CsrfHeaderFilter.CSRF_TOKEN_COOKE_NAME)
.logoutUrl(LOGOUT_URL)
.invalidateHttpSession(true)
.logoutSuccessHandler(logoutSuccessHandler()) //커스텀으로 로그아웃된거에 대한 처리를 해주면 로그아웃성공URL로 가지 않으니 커스텀할떄 사용해여라
.permitAll()
.and()
.addFilter(filterSecurityInterceptor);
}
}
@Slf4j
public class FilterInvocationSecurityMetadataSource implements org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource {
@Override
public Collection<ConfigAttribute> getAttributes(Object object){
FilterInvocation fi = (FilterInvocation) object;
HttpServletRequest request = fi.getHttpRequest();
String uri = request.getRequestURI();
String method = request.getMethod();
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
log.debug("url:{}, method:{}, Authentication:{} FilterInvocationSecurityMetadataSource >> {}", uri, method, authentication, object.toString());
List<ConfigAttribute> attributes = new ArrayList<>();
if(uri.startsWith("/swagger") || uri.startsWith("/v2/api-docs")){
attributes.add(new com.omnicns.web.spring.security.ConfigAttribute("ROLE_AUTH"));
}
//...
return attributes;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return Collections.emptyList();
}
@Override
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "T_ADMIN")
@Slf4j
@NamedEntityGraph(name = "UserDetails.auths", attributeNodes = @NamedAttributeNode("auths"))
public class UserDetails extends AdmBase implements Serializable, org.springframework.security.core.userdetails.UserDetails {
@OneToMany
@JoinColumn(name = "ADM_SEQ", referencedColumnName = "ADM_SEQ", insertable = false, updatable = false)
@OrderBy(value = "menuLvl, menuOrd, prntUrlSeq asc")
List<Auth> auths;
@Override
public Collection<? extends GrantedObjAuthority<List<Auth>>> getAuthorities() {
Map<String, GrantedObjAuthority<List<Auth>>> contain = new HashMap<>();
for (Auth auth : ListUtils.emptyIfNull(auths)) {
GrantedObjAuthority<List<Auth>> selectedAuths = Optional.ofNullable(contain.get(auth.getAuthId())).orElseGet(() -> {
GrantedObjAuthority<List<Auth>> newAuths = new GrantedObjAuthority<>(auth.getAuthId(), new ArrayList<>());
contain.put(auth.getAuthId(), newAuths);
return newAuths;
});
selectedAuths.getAuth().add(auth);
}contain.put("ROLE_AUTH", new GrantedObjAuthority<List<Auth>>("ROLE_AUTH", null));
return contain.values();
}
@JsonIgnore
@Override
public String getPassword() {
return getAdmLginPw();
}
@Override
public String getUsername() {
return getAdmNm();
}
@Override
public boolean isAccountNonExpired() {
return UseCd.USE001.equals(getUseCd());
}
@Override
public boolean isAccountNonLocked() {
return UseCd.USE001.equals(getUseCd());
}
@Override
public boolean isCredentialsNonExpired() {
return UseCd.USE001.equals(getUseCd());
}
@Override
public boolean isEnabled() {
return UseCd.USE001.equals(getUseCd());
}
}https://github.com/visualkhh/lib-spring/tree/master/boot/single-angular-swagger-jpa-typescript
'IT > spring' 카테고리의 다른 글
spring 다국어처리 2가지 session, Accept-Language (0) 2021.02.08 logback 5분 마다 logfile 생성하기 (0) 2021.02.05 spring boot oaauth2.0 (링크 정리 공유) (0) 2021.02.04 spring boot 정리 (locale, messageSource, security, jpa, hibernate, Scheduler, config) (0) 2021.02.04 spring boot 에서 JOOQ 사용시, 구동 1분이상 느려짐 현상 (버그) (0) 2021.02.04