Tomcat иногда отвечает 403 при входе с Keycloak, а иногда нет - PullRequest
0 голосов
/ 06 июня 2018

У меня есть 2 приложения (Spring Boot и Spring MVC), оба они развернуты в Tocmcat, как

localhost:9595/bootapp/   

и

localhost:9595/mvcapp/

Я зарегистрировал их какKeycloak client:

my_client

У меня 2 пользователя userA с ролью (MVC_USER, BOOT_USER) и userB с ролями (BOOT_USER)

1. Чтобы зарегистрировать загрузочное приложение, я использовал эти конфиги в своем приложении.properties:

keycloak.auth-server-url=http://10.60.6.34:8282/auth
keycloak.realm=IAP
keycloak.resource=my_client
keycloak.public-client=true
keycloak.principal-attribute=preferred_username

и вот мой класс конфигурации безопасности:

 @Configuration
 @EnableWebSecurity
 @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
    keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
    auth.authenticationProvider(keycloakAuthenticationProvider);
}

//keycloakConfigResolver: this defines that we want to use the Spring Boot properties file support instead of the default keycloak.json
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
}

@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
    return new RegisterSessionAuthenticationStrategy(buildSessionRegistry());
}

@Bean
protected SessionRegistry buildSessionRegistry() {
    return new SessionRegistryImpl();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http
            .csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/user").hasRole("BOOT_USER")
            .antMatchers("/main").hasRole("uma_authorization");
}

@Autowired
public KeycloakClientRequestFactory keycloakClientRequestFactory;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate keycloakRestTemplate(){
    return new KeycloakRestTemplate(keycloakClientRequestFactory);
}


}`

Для регистрации mvcapp я добавил это в файл META-INF / context.xml:

<Context> <Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/> </Context>

2.1.добавлен keycloak.json в WEB-INF:

{
 "realm": "IAP",
 "auth-server-url": "http://10.60.6.34:8282/auth",
 "resource": "my_app",
 "public-client": true,
 "confidential-port": 0,
 "principal-attribute":"preferred_username"
}

2.2. И добавлен web.xml в WEB-INF со следующим содержимым:

<web-app 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 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     version="3.0">



<security-constraint>
    <web-resource-collection>
        <web-resource-name>NSI</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>MVC_USER</role-name>
    </auth-constraint>
</security-constraint>


<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>this is ignored currently</realm-name>
</login-config>

<security-role>
    <role-name>admin</role-name>
</security-role>
<security-role>
    <role-name>MVC_USER</role-name>
</security-role>

MyЦелевая страница находится в Bootapp, поэтому у меня есть файл main.jsp со ссылкой, которая перенаправляет на mvcapp.

МОЯ ПРОБЛЕМА:

например, я набираю:

localhost: 9595 / bootapp

Появляется страница входа Keycloak.Я вхожу в систему с пользователем B (который имеет только роль BOOT_USER), и появляется целевая страница main.jsp из Bootapp.Когда я пытаюсь перенаправить приложение mvc, нажав на ссылку, Tomcat выдает ошибку 403, как и ожидалось, потому что userB не имеет роли MVC_USER.Хорошо!

Затем, когда я набираю это в строке URL в браузере:

http://localhost:9595/bootapp/sso/logout

я выхожу, как и ожидалось.

НО

При повторном входе в систему пользователя userA, у которого есть роли (USER_MVC и USER_BOOT), я по-прежнему вижу main.jsp НО, когда пытаюсь посетить

http://localhost:9595/mvcapp/

Tomcat выбрасывает 403!Даже если пользователь A имеет требуемую роль (USER_MVC).

Кстати:

Если я открою новое окно в режиме инкогнито и войдите в систему с помощью userA first (не с userBкак и раньше), у меня есть доступ как к Bootapp, так и к mvcapp, а после выхода и повторного входа в систему с помощью userB (который не должен иметь доступ к mvcapp), у меня также есть доступ к Bootapp и mvcapp.

Кажется, мне нужно отправить какой-то токен или что-то в mvcapp, но что?И как?Но если так, то как пользователь может оценить mvcapp при входе в систему через userA?(Я новичок во всем этом аутентичном материале)

Прошло некоторое время с тех пор, как я пытался найти решение, но я не мог.Пожалуйста, помогите!

1 Ответ

0 голосов
/ 27 июня 2018

Я предложу небольшие изменения.Я не уверен, в чем проблема.Но вы можете попробовать их и получить обратную связь, пожалуйста.

Попробуйте изменить свой тип доступа клиентов Keycloak на «конфиденциальный», вы используете этот параметр как «public»

ваш файл свойств sso включает=>

keycloak.public-client=true

когда вы изменили на «конфиденциальный», вы должны изменить конфигурацию sso следующим образом (это для загрузочного приложения. Точно так же, вам нужно изменить для приложения mvc.) =>

keycloak.realm=IAP
keycloak.auth-server-url=http://10.60.6.34:8282/auth
keycloak.ssl-required=external
keycloak.resource=my_client
keycloak.principal-attribute=preferred_username
keycloak.credentials.secret= /* your client secret you will reach this under 
                               "instalation tab" of IAP client

Попробуйте удалить «JSESSIONID» при выходе из сервера, для загрузочного приложения вы можете добавить этот блок кода в ваш класс SecurityConfig (метод настройки)

.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)

=>

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests() 
    .....
    .....
    .and().logout().logoutUrl("*log out url*")
                        .clearAuthentication(true)
                        .deleteCookies("JSESSIONID")
                        .invalidateHttpSession(true)
    .....
    .....
}
...