Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GRANDGERARD Gilles
keycloak-protocol-cas
Commits
7f7e0cce
Commit
7f7e0cce
authored
Jan 27, 2017
by
Matthias Piepkorn
Browse files
Add protocol SPIs, endpoints for login/logout/serviceValidate and some
claim mapper stubs
parent
8c35d0ab
Changes
18
Show whitespace changes
Inline
Side-by-side
pom.xml
0 → 100644
View file @
7f7e0cce
<?xml version="1.0"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
org.keycloak
</groupId>
<artifactId>
keycloak-protocol-cas
</artifactId>
<version>
1.0.0-SNAPSHOT
</version>
<name>
Keycloak CAS Protocol
</name>
<description
/>
<properties>
<keycloak.version>
2.5.1.Final
</keycloak.version>
<jboss.logging.version>
3.3.0.Final
</jboss.logging.version>
<jboss.logging.tools.version>
2.0.1.Final
</jboss.logging.tools.version>
<junit.version>
4.12
</junit.version>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<maven.compiler.target>
1.8
</maven.compiler.target>
<maven.compiler.source>
1.8
</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>
org.keycloak
</groupId>
<artifactId>
keycloak-core
</artifactId>
<version>
${keycloak.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.keycloak
</groupId>
<artifactId>
keycloak-server-spi
</artifactId>
<version>
${keycloak.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.keycloak
</groupId>
<artifactId>
keycloak-server-spi-private
</artifactId>
<version>
${keycloak.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.jboss.logging
</groupId>
<artifactId>
jboss-logging
</artifactId>
<version>
${jboss.logging.version}
</version>
</dependency>
<dependency>
<groupId>
org.jboss.logging
</groupId>
<artifactId>
jboss-logging-annotations
</artifactId>
<version>
${jboss.logging.tools.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
org.jboss.logging
</groupId>
<artifactId>
jboss-logging-processor
</artifactId>
<version>
${jboss.logging.tools.version}
</version>
<scope>
provided
</scope>
<optional>
true
</optional>
</dependency>
<dependency>
<groupId>
org.keycloak
</groupId>
<artifactId>
keycloak-services
</artifactId>
<version>
${keycloak.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
${junit.version}
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.1
</version>
<configuration>
<source>
${maven.compiler.source}
</source>
<target>
${maven.compiler.target}
</target>
<compilerArgument>
-AgeneratedTranslationFilesPath=${project.build.directory}/generated-translation-files
</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
</project>
src/main/java/org/keycloak/protocol/cas/CASLoginProtocol.java
0 → 100644
View file @
7f7e0cce
package
org.keycloak.protocol.cas
;
import
org.keycloak.common.util.KeycloakUriBuilder
;
import
org.keycloak.events.EventBuilder
;
import
org.keycloak.events.EventType
;
import
org.keycloak.models.*
;
import
org.keycloak.protocol.LoginProtocol
;
import
org.keycloak.services.managers.ClientSessionCode
;
import
org.keycloak.services.managers.ResourceAdminManager
;
import
javax.ws.rs.core.HttpHeaders
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriInfo
;
import
java.net.URI
;
public
class
CASLoginProtocol
implements
LoginProtocol
{
public
static
final
String
LOGIN_PROTOCOL
=
"cas"
;
public
static
final
String
SERVICE_PARAM
=
"service"
;
public
static
final
String
RENEW_PARAM
=
"renew"
;
public
static
final
String
GATEWAY_PARAM
=
"gateway"
;
public
static
final
String
TICKET_PARAM
=
"ticket"
;
public
static
final
String
FORMAT_PARAM
=
"format"
;
public
static
final
String
TICKET_RESPONSE_PARAM
=
"ticket"
;
public
static
final
String
SERVICE_TICKET_PREFIX
=
"ST-"
;
protected
KeycloakSession
session
;
protected
RealmModel
realm
;
protected
UriInfo
uriInfo
;
protected
HttpHeaders
headers
;
protected
EventBuilder
event
;
private
boolean
requireReauth
;
public
CASLoginProtocol
(
KeycloakSession
session
,
RealmModel
realm
,
UriInfo
uriInfo
,
HttpHeaders
headers
,
EventBuilder
event
,
boolean
requireReauth
)
{
this
.
session
=
session
;
this
.
realm
=
realm
;
this
.
uriInfo
=
uriInfo
;
this
.
headers
=
headers
;
this
.
event
=
event
;
this
.
requireReauth
=
requireReauth
;
}
public
CASLoginProtocol
()
{
}
@Override
public
CASLoginProtocol
setSession
(
KeycloakSession
session
)
{
this
.
session
=
session
;
return
this
;
}
@Override
public
CASLoginProtocol
setRealm
(
RealmModel
realm
)
{
this
.
realm
=
realm
;
return
this
;
}
@Override
public
CASLoginProtocol
setUriInfo
(
UriInfo
uriInfo
)
{
this
.
uriInfo
=
uriInfo
;
return
this
;
}
@Override
public
CASLoginProtocol
setHttpHeaders
(
HttpHeaders
headers
)
{
this
.
headers
=
headers
;
return
this
;
}
@Override
public
CASLoginProtocol
setEventBuilder
(
EventBuilder
event
)
{
this
.
event
=
event
;
return
this
;
}
@Override
public
Response
authenticated
(
UserSessionModel
userSession
,
ClientSessionCode
accessCode
)
{
ClientSessionModel
clientSession
=
accessCode
.
getClientSession
();
String
service
=
clientSession
.
getRedirectUri
();
//TODO validate service
accessCode
.
setAction
(
ClientSessionModel
.
Action
.
CODE_TO_TOKEN
.
name
());
KeycloakUriBuilder
uriBuilder
=
KeycloakUriBuilder
.
fromUri
(
service
);
uriBuilder
.
queryParam
(
TICKET_RESPONSE_PARAM
,
SERVICE_TICKET_PREFIX
+
accessCode
.
getCode
());
URI
redirectUri
=
uriBuilder
.
build
();
Response
.
ResponseBuilder
location
=
Response
.
status
(
302
).
location
(
redirectUri
);
return
location
.
build
();
}
@Override
public
Response
sendError
(
ClientSessionModel
clientSession
,
Error
error
)
{
return
Response
.
serverError
().
entity
(
error
).
build
();
}
@Override
public
void
backchannelLogout
(
UserSessionModel
userSession
,
ClientSessionModel
clientSession
)
{
ClientModel
client
=
clientSession
.
getClient
();
new
ResourceAdminManager
(
session
).
logoutClientSession
(
uriInfo
.
getRequestUri
(),
realm
,
client
,
clientSession
);
}
@Override
public
Response
frontchannelLogout
(
UserSessionModel
userSession
,
ClientSessionModel
clientSession
)
{
// todo oidc redirect support
throw
new
RuntimeException
(
"NOT IMPLEMENTED"
);
}
@Override
public
Response
finishLogout
(
UserSessionModel
userSession
)
{
event
.
event
(
EventType
.
LOGOUT
);
event
.
user
(
userSession
.
getUser
()).
session
(
userSession
).
success
();
return
Response
.
ok
().
build
();
}
@Override
public
boolean
requireReauthentication
(
UserSessionModel
userSession
,
ClientSessionModel
clientSession
)
{
return
requireReauth
;
}
@Override
public
void
close
()
{
}
}
src/main/java/org/keycloak/protocol/cas/CASLoginProtocolFactory.java
0 → 100644
View file @
7f7e0cce
package
org.keycloak.protocol.cas
;
import
org.jboss.logging.Logger
;
import
org.keycloak.events.EventBuilder
;
import
org.keycloak.models.*
;
import
org.keycloak.protocol.AbstractLoginProtocolFactory
;
import
org.keycloak.protocol.LoginProtocol
;
import
org.keycloak.protocol.ProtocolMapperUtils
;
import
org.keycloak.protocol.cas.mappers.FullNameMapper
;
import
org.keycloak.protocol.cas.mappers.UserAttributeMapper
;
import
org.keycloak.protocol.cas.mappers.UserPropertyMapper
;
import
org.keycloak.representations.idm.ClientRepresentation
;
import
org.keycloak.representations.idm.ClientTemplateRepresentation
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
keycloak
.
protocol
.
oidc
.
mappers
.
OIDCAttributeMapperHelper
.
JSON_TYPE
;
import
static
org
.
keycloak
.
protocol
.
oidc
.
mappers
.
OIDCAttributeMapperHelper
.
TOKEN_CLAIM_NAME
;
public
class
CASLoginProtocolFactory
extends
AbstractLoginProtocolFactory
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
CASLoginProtocolFactory
.
class
);
public
static
final
String
EMAIL
=
"email"
;
public
static
final
String
EMAIL_VERIFIED
=
"email verified"
;
public
static
final
String
GIVEN_NAME
=
"given name"
;
public
static
final
String
FAMILY_NAME
=
"family name"
;
public
static
final
String
FULL_NAME
=
"full name"
;
public
static
final
String
LOCALE
=
"locale"
;
public
static
final
String
EMAIL_CONSENT_TEXT
=
"${email}"
;
public
static
final
String
EMAIL_VERIFIED_CONSENT_TEXT
=
"${emailVerified}"
;
public
static
final
String
GIVEN_NAME_CONSENT_TEXT
=
"${givenName}"
;
public
static
final
String
FAMILY_NAME_CONSENT_TEXT
=
"${familyName}"
;
public
static
final
String
FULL_NAME_CONSENT_TEXT
=
"${fullName}"
;
public
static
final
String
LOCALE_CONSENT_TEXT
=
"${locale}"
;
@Override
public
LoginProtocol
create
(
KeycloakSession
session
)
{
return
new
CASLoginProtocol
().
setSession
(
session
);
}
@Override
public
List
<
ProtocolMapperModel
>
getBuiltinMappers
()
{
return
builtins
;
}
@Override
public
List
<
ProtocolMapperModel
>
getDefaultBuiltinMappers
()
{
return
defaultBuiltins
;
}
static
List
<
ProtocolMapperModel
>
builtins
=
new
ArrayList
<>();
static
List
<
ProtocolMapperModel
>
defaultBuiltins
=
new
ArrayList
<>();
static
{
ProtocolMapperModel
model
;
model
=
UserPropertyMapper
.
create
(
EMAIL
,
"email"
,
"mail"
,
"String"
,
true
,
EMAIL_CONSENT_TEXT
);
builtins
.
add
(
model
);
defaultBuiltins
.
add
(
model
);
model
=
UserPropertyMapper
.
create
(
GIVEN_NAME
,
"firstName"
,
"givenName"
,
"String"
,
true
,
GIVEN_NAME_CONSENT_TEXT
);
builtins
.
add
(
model
);
defaultBuiltins
.
add
(
model
);
model
=
UserPropertyMapper
.
create
(
FAMILY_NAME
,
"lastName"
,
"sn"
,
"String"
,
true
,
FAMILY_NAME_CONSENT_TEXT
);
builtins
.
add
(
model
);
defaultBuiltins
.
add
(
model
);
model
=
UserPropertyMapper
.
create
(
EMAIL_VERIFIED
,
"emailVerified"
,
"emailVerified"
,
"boolean"
,
false
,
EMAIL_VERIFIED_CONSENT_TEXT
);
builtins
.
add
(
model
);
model
=
UserAttributeMapper
.
create
(
LOCALE
,
"locale"
,
"locale"
,
"String"
,
false
,
LOCALE_CONSENT_TEXT
,
false
);
builtins
.
add
(
model
);
model
=
FullNameMapper
.
create
(
FULL_NAME
,
"cn"
,
true
,
FULL_NAME_CONSENT_TEXT
);
builtins
.
add
(
model
);
defaultBuiltins
.
add
(
model
);
}
@Override
protected
void
addDefaults
(
ClientModel
client
)
{
for
(
ProtocolMapperModel
model
:
defaultBuiltins
)
client
.
addProtocolMapper
(
model
);
}
@Override
public
Object
createProtocolEndpoint
(
RealmModel
realm
,
EventBuilder
event
)
{
return
new
CASLoginProtocolService
(
realm
,
event
);
}
@Override
public
String
getId
()
{
return
CASLoginProtocol
.
LOGIN_PROTOCOL
;
}
@Override
public
void
setupClientDefaults
(
ClientRepresentation
rep
,
ClientModel
newClient
)
{
if
(
rep
.
getRootUrl
()
!=
null
&&
(
rep
.
getRedirectUris
()
==
null
||
rep
.
getRedirectUris
().
isEmpty
()))
{
String
root
=
rep
.
getRootUrl
();
if
(
root
.
endsWith
(
"/"
))
root
=
root
+
"*"
;
else
root
=
root
+
"/*"
;
newClient
.
addRedirectUri
(
root
);
}
if
(
rep
.
getAdminUrl
()
==
null
&&
rep
.
getRootUrl
()
!=
null
)
{
newClient
.
setManagementUrl
(
rep
.
getRootUrl
());
}
}
@Override
public
void
setupTemplateDefaults
(
ClientTemplateRepresentation
clientRep
,
ClientTemplateModel
newClient
)
{
}
}
src/main/java/org/keycloak/protocol/cas/CASLoginProtocolService.java
0 → 100644
View file @
7f7e0cce
package
org.keycloak.protocol.cas
;
import
org.jboss.resteasy.spi.HttpRequest
;
import
org.jboss.resteasy.spi.ResteasyProviderFactory
;
import
org.keycloak.events.EventBuilder
;
import
org.keycloak.models.KeycloakSession
;
import
org.keycloak.models.RealmModel
;
import
org.keycloak.protocol.cas.endpoints.AuthorizationEndpoint
;
import
org.keycloak.protocol.cas.endpoints.LogoutEndpoint
;
import
org.keycloak.protocol.cas.endpoints.ServiceValidateEndpoint
;
import
org.keycloak.protocol.cas.endpoints.ValidateEndpoint
;
import
org.keycloak.services.resources.RealmsResource
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.HttpHeaders
;
import
javax.ws.rs.core.UriBuilder
;
import
javax.ws.rs.core.UriInfo
;
public
class
CASLoginProtocolService
{
private
RealmModel
realm
;
private
EventBuilder
event
;
@Context
private
UriInfo
uriInfo
;
@Context
private
KeycloakSession
session
;
@Context
private
HttpHeaders
headers
;
@Context
private
HttpRequest
request
;
public
CASLoginProtocolService
(
RealmModel
realm
,
EventBuilder
event
)
{
this
.
realm
=
realm
;
this
.
event
=
event
;
}
public
static
UriBuilder
serviceBaseUrl
(
UriBuilder
baseUriBuilder
)
{
return
baseUriBuilder
.
path
(
RealmsResource
.
class
).
path
(
"{realm}/protocol/"
+
CASLoginProtocol
.
LOGIN_PROTOCOL
);
}
@Path
(
"login"
)
public
Object
login
()
{
AuthorizationEndpoint
endpoint
=
new
AuthorizationEndpoint
(
realm
,
event
);
ResteasyProviderFactory
.
getInstance
().
injectProperties
(
endpoint
);
return
endpoint
;
}
@Path
(
"logout"
)
public
Object
logout
()
{
LogoutEndpoint
endpoint
=
new
LogoutEndpoint
(
realm
,
event
);
ResteasyProviderFactory
.
getInstance
().
injectProperties
(
endpoint
);
return
endpoint
;
}
@Path
(
"validate"
)
public
Object
validate
()
{
ValidateEndpoint
endpoint
=
new
ValidateEndpoint
(
realm
,
event
);
ResteasyProviderFactory
.
getInstance
().
injectProperties
(
endpoint
);
return
endpoint
;
}
@Path
(
"serviceValidate"
)
public
Object
serviceValidate
()
{
ServiceValidateEndpoint
endpoint
=
new
ServiceValidateEndpoint
(
realm
,
event
);
ResteasyProviderFactory
.
getInstance
().
injectProperties
(
endpoint
);
return
endpoint
;
}
@Path
(
"proxyValidate"
)
public
Object
proxyValidate
()
{
return
null
;
}
@Path
(
"proxy"
)
public
Object
proxy
()
{
return
null
;
}
@Path
(
"p3/serviceValidate"
)
public
Object
p3ServiceValidate
()
{
return
serviceValidate
();
}
@Path
(
"p3/proxyValidate"
)
public
Object
p3ProxyValidate
()
{
return
proxyValidate
();
}
}
src/main/java/org/keycloak/protocol/cas/endpoints/AuthorizationEndpoint.java
0 → 100644
View file @
7f7e0cce
package
org.keycloak.protocol.cas.endpoints
;
import
org.jboss.logging.Logger
;
import
org.keycloak.events.Details
;
import
org.keycloak.events.Errors
;
import
org.keycloak.events.EventBuilder
;
import
org.keycloak.events.EventType
;
import
org.keycloak.models.ClientModel
;
import
org.keycloak.models.ClientSessionModel
;
import
org.keycloak.models.RealmModel
;
import
org.keycloak.protocol.AuthorizationEndpointBase
;
import
org.keycloak.protocol.cas.CASLoginProtocol
;
import
org.keycloak.protocol.oidc.utils.RedirectUtils
;
import
org.keycloak.services.ErrorPageException
;
import
org.keycloak.services.messages.Messages
;
import
org.keycloak.services.util.CacheControlUtil
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.core.MultivaluedMap
;
import
javax.ws.rs.core.Response
;
public
class
AuthorizationEndpoint
extends
AuthorizationEndpointBase
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
AuthorizationEndpoint
.
class
);
private
ClientModel
client
;
private
ClientSessionModel
clientSession
;
private
String
redirectUri
;
public
AuthorizationEndpoint
(
RealmModel
realm
,
EventBuilder
event
)
{
super
(
realm
,
event
);
event
.
event
(
EventType
.
LOGIN
);
}
@GET
public
Response
build
()
{
MultivaluedMap
<
String
,
String
>
params
=
uriInfo
.
getQueryParameters
();
String
service
=
params
.
getFirst
(
CASLoginProtocol
.
SERVICE_PARAM
);
boolean
renew
=
"true"
.
equalsIgnoreCase
(
params
.
getFirst
(
CASLoginProtocol
.
RENEW_PARAM
));
boolean
gateway
=
"true"
.
equalsIgnoreCase
(
params
.
getFirst
(
CASLoginProtocol
.
GATEWAY_PARAM
));
checkSsl
();
checkRealm
();
checkClient
(
service
);
createClientSession
();
// So back button doesn't work
CacheControlUtil
.
noBackButtonCacheControlHeader
();
this
.
event
.
event
(
EventType
.
LOGIN
);
return
handleBrowserAuthenticationRequest
(
clientSession
,
new
CASLoginProtocol
(
session
,
realm
,
uriInfo
,
headers
,
event
,
renew
),
gateway
,
false
);
}
private
void
checkSsl
()
{
if
(!
uriInfo
.
getBaseUri
().
getScheme
().
equals
(
"https"
)
&&
realm
.
getSslRequired
().
isRequired
(
clientConnection
))
{
event
.
error
(
Errors
.
SSL_REQUIRED
);
throw
new
ErrorPageException
(
session
,
Messages
.
HTTPS_REQUIRED
);
}
}
private
void
checkRealm
()
{
if
(!
realm
.
isEnabled
())
{
event
.
error
(
Errors
.
REALM_DISABLED
);
throw
new
ErrorPageException
(
session
,
Messages
.
REALM_NOT_ENABLED
);
}
}
private
void
checkClient
(
String
service
)
{
if
(
service
==
null
)
{
event
.
error
(
Errors
.
INVALID_REQUEST
);
throw
new
ErrorPageException
(
session
,
Messages
.
MISSING_PARAMETER
,
CASLoginProtocol
.
SERVICE_PARAM
);
}
client
=
realm
.
getClients
().
stream
()
.
filter
(
c
->
CASLoginProtocol
.
LOGIN_PROTOCOL
.
equals
(
c
.
getProtocol
()))
.
filter
(
c
->
RedirectUtils
.
verifyRedirectUri
(
uriInfo
,
service
,
realm
,
c
)
!=
null
)
.
findFirst
().
orElse
(
null
);
if
(
client
==
null
)
{
event
.
error
(
Errors
.
CLIENT_NOT_FOUND
);
throw
new
ErrorPageException
(
session
,
Messages
.
CLIENT_NOT_FOUND
);
}
if
(!
client
.
isEnabled
())
{
event
.
error
(
Errors
.
CLIENT_DISABLED
);
throw
new
ErrorPageException
(
session
,
Messages
.
CLIENT_DISABLED
);
}
if
(
client
.
isBearerOnly
())
{
event
.
error
(
Errors
.
NOT_ALLOWED
);
throw
new
ErrorPageException
(
session
,
Messages
.
BEARER_ONLY
);
}
redirectUri
=
RedirectUtils
.
verifyRedirectUri
(
uriInfo
,
service
,
realm
,
client
);
event
.
client
(
client
.
getClientId
());
event
.
detail
(
Details
.
REDIRECT_URI
,
redirectUri
);
session
.
getContext
().
setClient
(
client
);
}
private
void
createClientSession
()
{
clientSession
=
session
.
sessions
().
createClientSession
(
realm
,
client
);
clientSession
.
setAuthMethod
(
CASLoginProtocol
.
LOGIN_PROTOCOL
);
clientSession
.
setRedirectUri
(
redirectUri
);
clientSession
.
setAction
(
ClientSessionModel
.
Action
.
AUTHENTICATE
.
name
());
}
}
src/main/java/org/keycloak/protocol/cas/endpoints/LogoutEndpoint.java
0 → 100644
View file @
7f7e0cce
package
org.keycloak.protocol.cas.endpoints
;
import
org.jboss.logging.Logger
;
import
org.jboss.resteasy.annotations.cache.NoCache
;
import
org.jboss.resteasy.spi.HttpRequest
;
import
org.keycloak.common.ClientConnection
;
import
org.keycloak.events.EventBuilder
;
import
org.keycloak.models.KeycloakSession
;
import
org.keycloak.models.RealmModel
;
import
org.keycloak.models.UserSessionModel
;
import
org.keycloak.protocol.cas.CASLoginProtocol
;
import
org.keycloak.services.managers.AuthenticationManager
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.core.Context
;
import
javax.ws.rs.core.HttpHeaders
;
import
javax.ws.rs.core.Response
;
import
javax.ws.rs.core.UriInfo
;
public
class
LogoutEndpoint
{
private
static
final
Logger
logger
=
Logger
.
getLogger
(
org
.
keycloak
.
protocol
.
oidc
.
endpoints
.
LogoutEndpoint
.
class
);
@Context
private
KeycloakSession
session
;
@Context