Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke 2014-08-01 13:18:46 -04:00
commit bdc31d9459
100 changed files with 415 additions and 255 deletions

View file

@ -1,4 +1,4 @@
package org.keycloak.services;
package org.keycloak;
/**
* Information about the client connection

View file

@ -0,0 +1,43 @@
package org.keycloak.enums;
import org.keycloak.ClientConnection;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public enum SslRequired {
ALL,
EXTERNAL,
NONE;
public boolean isRequired(ClientConnection connection) {
return isRequired(connection.getRemoteAddr());
}
public boolean isRequired(String address) {
switch (this) {
case ALL:
return true;
case NONE:
return false;
case EXTERNAL:
return !isLocal(address);
default:
return true;
}
}
private boolean isLocal(String remoteAddress) {
try {
InetAddress inetAddress = InetAddress.getByName(remoteAddress);
return inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isSiteLocalAddress();
} catch (UnknownHostException e) {
return false;
}
}
}

View file

@ -9,7 +9,7 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-required",
"resource", "credentials",
"use-resource-role-mappings",
"enable-cors", "cors-max-age", "cors-allowed-methods",

View file

@ -12,7 +12,7 @@ import java.util.Map;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-required",
"resource", "public-client", "credentials",
"use-resource-role-mappings",
"enable-cors", "cors-max-age", "cors-allowed-methods",

View file

@ -9,7 +9,7 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required"})
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-required"})
public class BaseRealmConfig {
@JsonProperty("realm")
protected String realm;
@ -17,15 +17,15 @@ public class BaseRealmConfig {
protected String realmKey;
@JsonProperty("auth-server-url")
protected String authServerUrl;
@JsonProperty("ssl-not-required")
protected boolean sslNotRequired;
@JsonProperty("ssl-required")
protected String sslRequired;
public boolean isSslNotRequired() {
return sslNotRequired;
public String getSslRequired() {
return sslRequired;
}
public void setSslNotRequired(boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
public void setSslRequired(String sslRequired) {
this.sslRequired = sslRequired;
}
public String getRealm() {

View file

@ -19,7 +19,7 @@ public class RealmRepresentation {
protected Integer accessCodeLifespan;
protected Integer accessCodeLifespanUserAction;
protected Boolean enabled;
protected Boolean sslNotRequired;
protected String sslRequired;
protected Boolean passwordCredentialGrantAllowed;
protected Boolean registrationAllowed;
protected Boolean rememberMe;
@ -121,12 +121,12 @@ public class RealmRepresentation {
this.enabled = enabled;
}
public Boolean isSslNotRequired() {
return sslNotRequired;
public String getSslRequired() {
return sslRequired;
}
public void setSslNotRequired(Boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
public void setSslRequired(String sslRequired) {
this.sslRequired = sslRequired;
}
public Integer getAccessTokenLifespan() {

View file

@ -6,6 +6,11 @@
<listitem>
DB Schema has changed again.
</listitem>
<listitem>
<literal>ssl-not-required</literal> property in adapter config has been removed. Replaced with
<literal>ssl-required</literal>, valid values are <literal>all</literal> (require SSL for all requests), <literal>external</literal>
(require SSL only for external request) and <literal>none</literal> (SSL not required).
</listitem>
</itemizedlist>
</sect1>
<sect1>

View file

@ -10,7 +10,7 @@
"resource" : "customer-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
"auth-server-url" : "https://localhost:8443/auth",
"ssl-not-required" : false,
"ssl-required" : "external",
"user-resource-role-mappings" : false,
"enable-cors" : true,
"cors-max-age" : 1000,
@ -89,14 +89,14 @@
</listitem>
</varlistentry>
<varlistentry>
<term>ssl-not-required</term>
<term>ssl-required</term>
<listitem>
<para>
Ensures that all communication to and from the Keycloak server from the adapter is over HTTPS.
This is <emphasis>OPTIONAL</emphasis>. The default value is
<emphasis>false</emphasis>
meaning
that HTTPS is required by default.
<emphasis>external</emphasis>
meaning that HTTPS is required by default for external requests. Valid values are 'all', 'external'
and 'none'.
</para>
</listitem>
</varlistentry>
@ -228,9 +228,9 @@
This is
<emphasis>OPTIONAL</emphasis>
if
<literal>ssl-not-required</literal>
<literal>ssl-required</literal>
is
<literal>false</literal>
<literal>none</literal>
or
<literal>disable-trust-manager</literal>
is <literal>true</literal>. The default value is<emphasis>false</emphasis>.

View file

@ -224,7 +224,7 @@ public class CustomerService {
<realm>demo</realm>
<realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA</realm-public-key>
<auth-server-url>http://localhost:8081/auth</auth-server-url>
<ssl-not-required>true</ssl-not-required>
<ssl-required>external</ssl-required>
<resource>customer-portal</resource>
<credential name="secret">password</credential>
</secure-deployment>
@ -255,7 +255,7 @@ public class CustomerService {
<realm name="demo">
<realm-public-key>MIGfMA0GCSqGSIb3DQEBA</realm-public-key>
<auth-server-url>http://localhost:8080/auth</auth-server-url>
<ssl-not-required>true</ssl-not-required>
<ssl-required>external</ssl-required>
</realm>
<secure-deployment name="customer-portal.war">
<realm>demo</realm>

View file

@ -1,7 +1,7 @@
{
"realm": "example",
"enabled": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",

View file

@ -2,7 +2,7 @@
"realm" : "cors",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"resource" : "angular-product",
"public-client" : true
}

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"updateProfileOnInitialSocialLogin": false,

View file

@ -3,6 +3,6 @@
"resource" : "database-service",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"bearer-only" : true,
"ssl-not-required": true,
"ssl-required": "external",
"enable-cors": true
}

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"resource" : "angular-product",
"public-client" : true
}

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"resource" : "customer-portal-cli",
"public-client" : true
}

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"resource" : "customer-portal-js",
"public-client" : true
}

View file

@ -3,7 +3,7 @@
"resource": "customer-portal",
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url": "/auth",
"ssl-not-required": true,
"ssl-required" : "external",
"expose-token": true,
"credentials": {
"secret": "password"

View file

@ -3,5 +3,5 @@
"resource" : "database-service",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"bearer-only" : true,
"ssl-not-required": true
"ssl-required" : "external"
}

View file

@ -3,7 +3,7 @@
"resource" : "product-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"credentials" : {
"secret": "password"
}

View file

@ -3,7 +3,7 @@
<realm name="demo">
<realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</realm-public-key>
<auth-server-url>/auth</auth-server-url>
<ssl-not-required>true</ssl-not-required>
<ssl-required>external</ssl-required>
</realm>
<secure-deployment name="customer-portal.war">
<realm>demo</realm>

View file

@ -7,7 +7,7 @@
"ssoSessionIdleTimeout": 600,
"ssoSessionMaxLifespan": 36000,
"passwordCredentialGrantAllowed": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"updateProfileOnInitialSocialLogin": false,
@ -30,6 +30,36 @@
"account": [ "manage-account" ]
}
},
{
"username" : "stian",
"enabled": true,
"email" : "stian@redhat.com",
"firstName": "Stian",
"lastName": "Thorgersen",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "mposolda@redhat.com",
"enabled": true,
"email" : "mposolda@redhat.com",
"firstName": "Marek",
"lastName": "Posolda",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
},
{
"username" : "admin",
"enabled": true,

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"resource" : "third-party",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"credentials" : {
"secret": "password"
}

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"resource" : "third-party",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"credentials" : {
"secret": "password"
}

View file

@ -1,7 +1,7 @@
{
"realm": "example",
"enabled": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",

View file

@ -2,7 +2,7 @@
"realm" : "example",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"resource" : "js-console",
"public-client" : true
}

View file

@ -197,8 +197,6 @@ module.controller('RealmCreateCtrl', function($scope, Current, Realm, $upload, $
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
var ssl = window.location.protocol == 'https:';
realmCopy.sslNotRequired = !ssl;
console.log('creating new realm **');
Realm.create(realmCopy, function() {
Realm.query(function(data) {
@ -230,7 +228,7 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, ser
if ($scope.createRealm) {
$scope.realm = {
enabled: true,
requireSsl: true
sslRequired: 'external'
};
} else {
if (Current.realm == null || Current.realm.realm != realm.realm) {
@ -256,7 +254,6 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, ser
}
*/
$scope.realm = angular.copy(realm);
$scope.realm.requireSsl = !realm.sslNotRequired;
}
$scope.social = $scope.realm.social;
@ -276,8 +273,6 @@ module.controller('RealmDetailCtrl', function($scope, Current, Realm, realm, ser
$scope.save = function() {
var realmCopy = angular.copy($scope.realm);
realmCopy.sslNotRequired = !realmCopy.requireSsl;
delete realmCopy["requireSsl"];
if ($scope.createRealm) {
Realm.save(realmCopy, function(data, headers) {
console.log('creating new realm');

View file

@ -73,9 +73,15 @@
</div>
</div>
<div class="form-group">
<label for="requireSsl" class="col-sm-2 control-label">Require SSL</label>
<label for="sslRequired" class="col-sm-2 control-label">Require SSL</label>
<div class="col-sm-4">
<input ng-model="realm.requireSsl" name="requireSsl" id="requireSsl" onoffswitch />
<div class="select-kc">
<select id="sslRequired" ng-model="realm.sslRequired">
<option value="all">all requests</option>
<option value="external">external requests</option>
<option value="none">none</option>
</select>
</div>
</div>
</div>
</fieldset>

View file

@ -5,6 +5,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.jboss.logging.Logger;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.representations.idm.PublishedRealmRepresentation;
import org.keycloak.util.JsonSerialization;
@ -187,12 +188,12 @@ public class AdapterDeploymentContext {
}
@Override
public boolean isSslRequired() {
return delegate.isSslRequired();
public SslRequired getSslRequired() {
return delegate.getSslRequired();
}
@Override
public void setSslRequired(boolean sslRequired) {
public void setSslRequired(SslRequired sslRequired) {
delegate.setSslRequired(sslRequired);
}
@ -281,10 +282,10 @@ public class AdapterDeploymentContext {
KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(base);
URI request = URI.create(facade.getRequest().getURI());
String scheme = request.getScheme();
if (deployment.isSslRequired()) {
if (deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
scheme = "https";
if (!request.getScheme().equals(scheme) && request.getPort() != -1) {
log.error("request scheme: " + request.getScheme() + " ssl required: " + deployment.isSslRequired());
log.error("request scheme: " + request.getScheme() + " ssl required");
throw new RuntimeException("Can't resolve relative url from adapter config.");
}
}

View file

@ -73,6 +73,8 @@ public interface HttpFacade {
String getHeader(String name);
List<String> getHeaders(String name);
InputStream getInputStream();
String getRemoteAddr();
}
interface Response {

View file

@ -4,6 +4,7 @@ import org.apache.http.client.HttpClient;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.ServiceUrlConstants;
import org.keycloak.enums.SslRequired;
import org.keycloak.util.KeycloakUriBuilder;
import java.net.URI;
@ -37,7 +38,7 @@ public class KeycloakDeployment {
protected HttpClient client;
protected String scope;
protected boolean sslRequired = true;
protected SslRequired sslRequired = SslRequired.ALL;
protected String stateCookieName = "OAuth_Token_Request_State";
protected boolean useResourceRoleMappings;
protected boolean cors;
@ -168,11 +169,11 @@ public class KeycloakDeployment {
this.scope = scope;
}
public boolean isSslRequired() {
public SslRequired getSslRequired() {
return sslRequired;
}
public void setSslRequired(boolean sslRequired) {
public void setSslRequired(SslRequired sslRequired) {
this.sslRequired = sslRequired;
}

View file

@ -4,6 +4,7 @@ import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.keycloak.OAuth2Constants;
import org.keycloak.ServiceUrlConstants;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.keycloak.util.KeycloakUriBuilder;
import org.keycloak.util.PemUtils;
@ -40,7 +41,11 @@ public class KeycloakDeploymentBuilder {
}
deployment.setRealmKey(realmKey);
}
deployment.setSslRequired(!adapterConfig.isSslNotRequired());
if (adapterConfig.getSslRequired() != null) {
deployment.setSslRequired(SslRequired.valueOf(adapterConfig.getSslRequired().toUpperCase()));
} else {
deployment.setSslRequired(SslRequired.EXTERNAL);
}
deployment.setResourceCredentials(adapterConfig.getCredentials());
deployment.setPublicClient(adapterConfig.isPublicClient());
deployment.setUseResourceRoleMappings(adapterConfig.isUseResourceRoleMappings());

View file

@ -110,7 +110,7 @@ public abstract class OAuthRequestAuthenticator {
protected String getRedirectUri(String state) {
String url = getRequestUrl();
log.infof("callback uri: %s", url);
if (!isRequestSecure() && deployment.isSslRequired()) {
if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
int port = sslRedirectPort();
if (port < 0) {
// disabled?
@ -150,7 +150,7 @@ public abstract class OAuthRequestAuthenticator {
}
log.info("Sending redirect to login page: " + redirect);
exchange.getResponse().setStatus(302);
exchange.getResponse().setCookie(deployment.getStateCookieName(), state, /* need to set path? */ null, null, -1, deployment.isSslRequired(), false);
exchange.getResponse().setCookie(deployment.getStateCookieName(), state, /* need to set path? */ null, null, -1, deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr()), false);
exchange.getResponse().setHeader("Location", redirect);
return true;
}
@ -241,8 +241,7 @@ public abstract class OAuthRequestAuthenticator {
*/
protected AuthChallenge resolveCode(String code) {
// abort if not HTTPS
if (deployment.isSslRequired() && !isRequestSecure()) {
if (!isRequestSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
log.error("Adapter requires SSL. Request: " + facade.getRequest().getURI());
return challenge(403);
}

View file

@ -153,7 +153,7 @@ public class PreAuthActionsHandler {
}
protected JWSInput verifyAdminRequest() throws Exception {
if (deployment.isSslRequired() && !facade.getRequest().isSecure()) {
if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
log.warn("SSL is required for adapter admin action");
facade.getResponse().sendError(403, "ssl required");

View file

@ -82,7 +82,7 @@ public abstract class RequestAuthenticator {
}
protected boolean verifySSL() {
if (!facade.getRequest().isSecure() && deployment.isSslRequired()) {
if (!facade.getRequest().isSecure() && deployment.getSslRequired().isRequired(facade.getRequest().getRemoteAddr())) {
log.warn("SSL is required to authenticate");
return true;
}

View file

@ -83,7 +83,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
list.add(addRealm);
@ -114,7 +114,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
* TODO need to check realm-ref first.
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
*/

View file

@ -54,7 +54,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler {
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
//TODO: externalize message
throw new OperationFailedException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new OperationFailedException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
}

View file

@ -45,11 +45,11 @@ public class SharedAttributeDefinitons {
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
.setXmlName("ssl-not-required")
protected static final SimpleAttributeDefinition SSL_REQUIRED =
new SimpleAttributeDefinitionBuilder("ssl-required", ModelType.STRING, true)
.setXmlName("ssl-required")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.setDefaultValue(new ModelNode("external"))
.build();
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
@ -138,7 +138,7 @@ public class SharedAttributeDefinitons {
ATTRIBUTES.add(AUTH_SERVER_URL);
ATTRIBUTES.add(TRUSTSTORE);
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
ATTRIBUTES.add(SSL_NOT_REQUIRED);
ATTRIBUTES.add(SSL_REQUIRED);
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
@ -153,20 +153,22 @@ public class SharedAttributeDefinitons {
}
/**
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
* truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.
*
* @param attributes The full set of attributes.
*
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
*/
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
return false;
}
if (isSet(attributes, DISABLE_TRUST_MANAGER)) {
return true;
}
return true;
if (isSet(attributes, SSL_REQUIRED) && attributes.get(SSL_REQUIRED.getName()).asString().equals("none")) {
return true;
}
return isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD);
}
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {

View file

@ -10,7 +10,7 @@ keycloak.realm.remove=Remove a realm from the subsystem.
keycloak.realm.realm-public-key=Public key of the realm
keycloak.realm.auth-server-url=Base URL of the Realm Auth Server
keycloak.realm.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.realm.ssl-not-required=SSL is not required for secure interactions
keycloak.realm.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.realm.allow-any-hostname=SSL Setting
keycloak.realm.truststore=Truststore used for adapter client HTTPS requests
keycloak.realm.truststore-password=Password of the Truststore
@ -31,7 +31,7 @@ keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
keycloak.secure-deployment.realm-public-key=Public key of the realm
keycloak.secure-deployment.auth-server-url=Base URL of the Realm Auth Server
keycloak.secure-deployment.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.secure-deployment.ssl-not-required=SSL is not required for secure interactions
keycloak.secure-deployment.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.secure-deployment.allow-any-hostname=SSL Setting
keycloak.secure-deployment.truststore=Truststore used for adapter client HTTPS requests
keycloak.secure-deployment.truststore-password=Password of the Truststore

View file

@ -69,7 +69,7 @@
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
<xs:element name="auth-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
<xs:element name="code-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>

View file

@ -47,28 +47,38 @@ public class RealmDefinitionTestCase {
@Test
public void testIsTruststoreSetIfRequired() throws Exception {
model.get("ssl-not-required").set(true);
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(true);
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(false);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");

View file

@ -87,6 +87,11 @@ public class CatalinaHttpFacade implements HttpFacade {
public String getHeader(String name) {
return request.getHeader(name);
}
@Override
public String getRemoteAddr() {
return request.getRemoteAddr();
}
}
protected class ResponseFacade implements Response {

View file

@ -86,6 +86,11 @@ public class CatalinaHttpFacade implements HttpFacade {
public String getHeader(String name) {
return request.getHeader(name);
}
@Override
public String getRemoteAddr() {
return request.getRemoteAddr();
}
}
protected class ResponseFacade implements Response {

View file

@ -102,6 +102,11 @@ public class UndertowHttpFacade implements HttpFacade {
public InputStream getInputStream() {
return exchange.getInputStream();
}
@Override
public String getRemoteAddr() {
return exchange.getSourceAddress().getAddress().getHostAddress();
}
}
protected class ResponseFacade implements Response {

View file

@ -83,7 +83,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
list.add(addRealm);
@ -114,7 +114,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
* TODO need to check realm-ref first.
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
*/

View file

@ -53,7 +53,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler {
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
//TODO: externalize message
throw new OperationFailedException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
throw new OperationFailedException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-maanger is false.");
}
}

View file

@ -44,11 +44,11 @@ public class SharedAttributeDefinitons {
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
.setXmlName("ssl-not-required")
protected static final SimpleAttributeDefinition SSL_REQUIRED =
new SimpleAttributeDefinitionBuilder("ssl-required", ModelType.STRING, true)
.setXmlName("ssl-required")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.setDefaultValue(new ModelNode("external"))
.build();
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
@ -137,7 +137,7 @@ public class SharedAttributeDefinitons {
ATTRIBUTES.add(AUTH_SERVER_URL);
ATTRIBUTES.add(TRUSTSTORE);
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
ATTRIBUTES.add(SSL_NOT_REQUIRED);
ATTRIBUTES.add(SSL_REQUIRED);
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
@ -152,20 +152,22 @@ public class SharedAttributeDefinitons {
}
/**
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
* truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.
*
* @param attributes The full set of attributes.
*
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
*/
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
return false;
}
if (isSet(attributes, DISABLE_TRUST_MANAGER)) {
return true;
}
return true;
if (isSet(attributes, SSL_REQUIRED) && attributes.get(SSL_REQUIRED.getName()).asString().equals("none")) {
return true;
}
return isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD);
}
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {

View file

@ -10,7 +10,7 @@ keycloak.realm.remove=Remove a realm from the subsystem.
keycloak.realm.realm-public-key=Public key of the realm
keycloak.realm.auth-server-url=Base URL of the Realm Auth Server
keycloak.realm.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.realm.ssl-not-required=SSL is not required for secure interactions
keycloak.realm.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.realm.allow-any-hostname=SSL Setting
keycloak.realm.truststore=Truststore used for adapter client HTTPS requests
keycloak.realm.truststore-password=Password of the Truststore
@ -31,7 +31,7 @@ keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
keycloak.secure-deployment.realm-public-key=Public key of the realm
keycloak.secure-deployment.auth-server-url=Base URL of the Realm Auth Server
keycloak.secure-deployment.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.secure-deployment.ssl-not-required=SSL is not required for secure interactions
keycloak.secure-deployment.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.secure-deployment.allow-any-hostname=SSL Setting
keycloak.secure-deployment.truststore=Truststore used for adapter client HTTPS requests
keycloak.secure-deployment.truststore-password=Password of the Truststore

View file

@ -39,7 +39,7 @@
<xs:element name="auth-server-url" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:all>
@ -71,7 +71,7 @@
<xs:element name="public-client" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="credential" type="credential-type" minOccurs="1" maxOccurs="1"/>
</xs:all>

View file

@ -48,28 +48,38 @@ public class RealmDefinitionTestCase {
@Test
public void testIsTruststoreSetIfRequired() throws Exception {
model.get("ssl-not-required").set(true);
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(true);
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(false);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-not-required").set(false);
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");

View file

@ -56,7 +56,7 @@ public class SubsystemParsingTestCase extends AbstractSubsystemTest {
node.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
node.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/tokens/login");
node.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes");
node.get("ssl-not-required").set(true);
node.get("ssl-required").set("external");
node.get("expose-token").set(true);
ModelNode credential = new ModelNode();
credential.get("password").set("password");

View file

@ -1,5 +1,7 @@
package org.keycloak.models;
import org.keycloak.enums.SslRequired;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.List;
@ -22,9 +24,9 @@ public interface RealmModel extends RoleContainerModel {
void setEnabled(boolean enabled);
boolean isSslNotRequired();
SslRequired getSslRequired();
void setSslNotRequired(boolean sslNotRequired);
void setSslRequired(SslRequired sslRequired);
boolean isRegistrationAllowed();

View file

@ -12,7 +12,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
private String name;
private boolean enabled;
private boolean sslNotRequired;
private String sslRequired;
private boolean registrationAllowed;
private boolean rememberMe;
private boolean verifyEmail;
@ -79,12 +79,12 @@ public class RealmEntity extends AbstractIdentifiableEntity {
this.enabled = enabled;
}
public boolean isSslNotRequired() {
return sslNotRequired;
public String getSslRequired() {
return sslRequired;
}
public void setSslNotRequired(boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
public void setSslRequired(String sslRequired) {
this.sslRequired = sslRequired;
}
public boolean isPasswordCredentialGrantAllowed() {

View file

@ -85,7 +85,7 @@ public class ModelToRepresentation {
rep.setSocial(realm.isSocial());
rep.setNotBefore(realm.getNotBefore());
rep.setUpdateProfileOnInitialSocialLogin(realm.isUpdateProfileOnInitialSocialLogin());
rep.setSslNotRequired(realm.isSslNotRequired());
rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
rep.setPublicKey(realm.getPublicKeyPem());
rep.setPrivateKey(realm.getPrivateKeyPem());
rep.setPasswordCredentialGrantAllowed(realm.isPasswordCredentialGrantAllowed());

View file

@ -17,6 +17,7 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserModel;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.AuthenticationLinkRepresentation;
@ -73,7 +74,7 @@ public class RepresentationToModel {
newRealm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
else newRealm.setAccessCodeLifespanUserAction(300);
if (rep.isSslNotRequired() != null) newRealm.setSslNotRequired(rep.isSslNotRequired());
if (rep.getSslRequired() != null) newRealm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
if (rep.isPasswordCredentialGrantAllowed() != null) newRealm.setPasswordCredentialGrantAllowed(rep.isPasswordCredentialGrantAllowed());
if (rep.isRegistrationAllowed() != null) newRealm.setRegistrationAllowed(rep.isRegistrationAllowed());
if (rep.isRememberMe() != null) newRealm.setRememberMe(rep.isRememberMe());
@ -249,7 +250,7 @@ public class RepresentationToModel {
if (rep.isResetPasswordAllowed() != null) realm.setResetPasswordAllowed(rep.isResetPasswordAllowed());
if (rep.isUpdateProfileOnInitialSocialLogin() != null)
realm.setUpdateProfileOnInitialSocialLogin(rep.isUpdateProfileOnInitialSocialLogin());
if (rep.isSslNotRequired() != null) realm.setSslNotRequired((rep.isSslNotRequired()));
if (rep.getSslRequired() != null) realm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase()));
if (rep.getAccessCodeLifespan() != null) realm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
if (rep.getAccessCodeLifespanUserAction() != null)
realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());

View file

@ -11,6 +11,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.entities.CachedRealm;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.security.PrivateKey;
@ -78,15 +79,15 @@ public class RealmAdapter implements RealmModel {
}
@Override
public boolean isSslNotRequired() {
if (updated != null) return updated.isSslNotRequired();
return cached.isSslNotRequired();
public SslRequired getSslRequired() {
if (updated != null) return updated.getSslRequired();
return cached.getSslRequired();
}
@Override
public void setSslNotRequired(boolean sslNotRequired) {
public void setSslRequired(SslRequired sslRequired) {
getDelegateForUpdate();
updated.setSslNotRequired(sslNotRequired);
updated.setSslRequired(sslRequired);
}
@Override

View file

@ -10,6 +10,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.cache.RealmCache;
import org.keycloak.enums.SslRequired;
import java.util.ArrayList;
import java.util.HashMap;
@ -28,7 +29,7 @@ public class CachedRealm {
private String id;
private String name;
private boolean enabled;
private boolean sslNotRequired;
private SslRequired sslRequired;
private boolean registrationAllowed;
private boolean rememberMe;
private boolean verifyEmail;
@ -86,7 +87,7 @@ public class CachedRealm {
id = model.getId();
name = model.getName();
enabled = model.isEnabled();
sslNotRequired = model.isSslNotRequired();
sslRequired = model.getSslRequired();
registrationAllowed = model.isRegistrationAllowed();
rememberMe = model.isRememberMe();
verifyEmail = model.isVerifyEmail();
@ -187,8 +188,8 @@ public class CachedRealm {
return enabled;
}
public boolean isSslNotRequired() {
return sslNotRequired;
public SslRequired getSslRequired() {
return sslRequired;
}
public boolean isRegistrationAllowed() {

View file

@ -3,8 +3,8 @@ package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
@ -86,13 +86,13 @@ public class RealmAdapter implements RealmModel {
}
@Override
public boolean isSslNotRequired() {
return realm.isSslNotRequired();
public SslRequired getSslRequired() {
return realm.getSslRequired() != null ? SslRequired.valueOf(realm.getSslRequired()) : null;
}
@Override
public void setSslNotRequired(boolean sslNotRequired) {
realm.setSslNotRequired(sslNotRequired);
public void setSslRequired(SslRequired sslRequired) {
realm.setSslRequired(sslRequired.name());
em.flush();
}

View file

@ -44,8 +44,8 @@ public class RealmEntity {
@Column(name="ENABLED")
protected boolean enabled;
@Column(name="SSL_NOT_REQUIRED")
protected boolean sslNotRequired;
@Column(name="SSL_REQUIRED")
protected String sslRequired;
@Column(name="REGISTRATION_ALLOWED")
protected boolean registrationAllowed;
@Column(name="PASSWORD_CRED_GRANT_ALLOWED")
@ -186,12 +186,12 @@ public class RealmEntity {
this.enabled = enabled;
}
public boolean isSslNotRequired() {
return sslNotRequired;
public String getSslRequired() {
return sslRequired;
}
public void setSslNotRequired(boolean sslNotRequired) {
this.sslNotRequired = sslNotRequired;
public void setSslRequired(String sslRequired) {
this.sslRequired = sslRequired;
}
public boolean isPasswordCredentialGrantAllowed() {

View file

@ -18,6 +18,7 @@ import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.entities.AuthenticationProviderEntity;
import org.keycloak.models.entities.RequiredCredentialEntity;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity;
import org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity;
@ -89,13 +90,13 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
}
@Override
public boolean isSslNotRequired() {
return realm.isSslNotRequired();
public SslRequired getSslRequired() {
return SslRequired.valueOf(realm.getSslRequired());
}
@Override
public void setSslNotRequired(boolean sslNotRequired) {
realm.setSslNotRequired(sslNotRequired);
public void setSslRequired(SslRequired sslRequired) {
realm.setSslRequired(sslRequired.name());
updateRealm();
}

View file

@ -1,6 +1,7 @@
package org.keycloak.example;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.enums.SslRequired;
import org.keycloak.representations.adapters.config.AdapterConfig;
import javax.servlet.ServletContextEvent;
@ -18,7 +19,7 @@ public class BootstrapListener implements ServletContextListener {
config.setRealm("aerogear");
config.setResource("unified-push-server");
config.setAuthServerUrl("/auth");
config.setSslNotRequired(true);
config.setSslRequired(SslRequired.EXTERNAL.name());
config.setPublicClient(true);
config.setDisableTrustManager(true);
deploymentContext.updateDeployment(config);

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"adminTheme": "aerogear",

View file

@ -1,7 +1,7 @@
package org.keycloak.services.filters;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import javax.servlet.Filter;
import javax.servlet.FilterChain;

View file

@ -2,6 +2,7 @@ package org.keycloak.services.managers;
import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.UnauthorizedException;
import org.keycloak.ClientConnection;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@ -18,12 +19,12 @@ public class AppAuthManager extends AuthenticationManager {
protected static Logger logger = Logger.getLogger(AppAuthManager.class);
@Override
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
AuthResult authResult = super.authenticateIdentityCookie(session, realm, uriInfo, headers);
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
AuthResult authResult = super.authenticateIdentityCookie(session, realm, uriInfo, connection, headers);
if (authResult == null) return null;
// refresh the cookies!
createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo);
if (authResult.getSession().isRememberMe()) createRememberMeCookie(realm, uriInfo);
createLoginCookie(realm, authResult.getUser(), authResult.getSession(), uriInfo, connection);
if (authResult.getSession().isRememberMe()) createRememberMeCookie(realm, uriInfo, connection);
return authResult;
}
@ -39,10 +40,10 @@ public class AppAuthManager extends AuthenticationManager {
return tokenString;
}
public AuthResult authenticateBearerToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
public AuthResult authenticateBearerToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
String tokenString = extractAuthorizationHeaderToken(headers);
if (tokenString == null) return null;
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, true, tokenString);
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, true, tokenString);
return authResult;
}

View file

@ -12,6 +12,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.CredentialRepresentation;
@ -57,7 +58,7 @@ public class ApplianceBootstrap {
realm.setSsoSessionMaxLifespan(36000);
realm.setAccessCodeLifespan(60);
realm.setAccessCodeLifespanUserAction(300);
realm.setSslNotRequired(true);
realm.setSslRequired(SslRequired.EXTERNAL);
realm.setRegistrationAllowed(false);
KeycloakModelUtils.generateRealmKeys(realm);
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));

View file

@ -46,7 +46,7 @@ public class ApplicationManager {
}
}
@JsonPropertyOrder({"realm", "realm-public-key", "bearer-only", "auth-server-url", "ssl-not-required",
@JsonPropertyOrder({"realm", "realm-public-key", "bearer-only", "auth-server-url", "ssl-required",
"resource", "public-client", "credentials",
"use-resource-role-mappings"})
public static class InstallationAdapterConfig extends BaseRealmConfig {
@ -107,7 +107,7 @@ public class ApplicationManager {
InstallationAdapterConfig rep = new InstallationAdapterConfig();
rep.setRealm(realmModel.getName());
rep.setRealmKey(realmModel.getPublicKeyPem());
rep.setSslNotRequired(realmModel.isSslNotRequired());
rep.setSslRequired(realmModel.getSslRequired().name().toLowerCase());
if (applicationModel.isPublicClient() && !applicationModel.isBearerOnly()) rep.setPublicClient(true);
if (applicationModel.isBearerOnly()) rep.setBearerOnly(true);
@ -140,7 +140,7 @@ public class ApplicationManager {
buffer.append(" <public-client>true</public-client>\n");
}
}
buffer.append(" <ssl-not-required>").append(realmModel.isSslNotRequired()).append("</ssl-not-required>\n");
buffer.append(" <ssl-required>").append(realmModel.getSslRequired().name()).append("</ssl-required>\n");
buffer.append(" <resource>").append(applicationModel.getName()).append("</resource>\n");
String cred = applicationModel.getSecret();
if (!applicationModel.isBearerOnly() && !applicationModel.isPublicClient()) {

View file

@ -6,7 +6,7 @@ import org.keycloak.audit.AuditListener;
import org.keycloak.audit.AuditProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import java.util.LinkedList;
import java.util.List;

View file

@ -17,7 +17,7 @@ import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.util.Time;
@ -63,15 +63,15 @@ public class AuthenticationManager {
return valid;
}
public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo) {
public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection) {
if (userSession == null) return;
UserModel user = userSession.getUser();
logger.infov("Logging out: {0} ({1})", user.getUsername(), userSession.getId());
session.sessions().removeUserSession(realm, userSession);
expireIdentityCookie(realm, uriInfo);
expireRememberMeCookie(realm, uriInfo);
expireIdentityCookie(realm, uriInfo, connection);
expireRememberMeCookie(realm, uriInfo, connection);
new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), userSession.getId());
@ -94,12 +94,12 @@ public class AuthenticationManager {
return token;
}
public void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo) {
public void createLoginCookie(RealmModel realm, UserModel user, UserSessionModel session, UriInfo uriInfo, ClientConnection connection) {
logger.info("createLoginCookie");
String cookiePath = getIdentityCookiePath(realm, uriInfo);
AccessToken identityToken = createIdentityToken(realm, user, session);
String encoded = encodeToken(realm, identityToken);
boolean secureOnly = !realm.isSslNotRequired();
boolean secureOnly = realm.getSslRequired().isRequired(connection);
logger.debugv("creatingLoginCookie - name: {0} path: {1}", KEYCLOAK_IDENTITY_COOKIE, cookiePath);
int maxAge = NewCookie.DEFAULT_MAX_AGE;
if (session.isRememberMe()) {
@ -119,9 +119,9 @@ public class AuthenticationManager {
}
public void createRememberMeCookie(RealmModel realm, UriInfo uriInfo) {
public void createRememberMeCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) {
String path = getIdentityCookiePath(realm, uriInfo);
boolean secureOnly = !realm.isSslNotRequired();
boolean secureOnly = realm.getSslRequired().isRequired(connection);
// remember me cookie should be persistent
//NewCookie cookie = new NewCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly);// todo httponly , true);
CookieHelper.addCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getSsoSessionIdleTimeout(), secureOnly, true);
@ -134,18 +134,18 @@ public class AuthenticationManager {
return encodedToken;
}
public static void expireIdentityCookie(RealmModel realm, UriInfo uriInfo) {
public static void expireIdentityCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) {
logger.debug("Expiring identity cookie");
String path = getIdentityCookiePath(realm, uriInfo);
expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, path, true);
expireCookie(realm, KEYCLOAK_SESSION_COOKIE, path, false);
expireRememberMeCookie(realm, uriInfo);
expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, path, true, connection);
expireCookie(realm, KEYCLOAK_SESSION_COOKIE, path, false, connection);
expireRememberMeCookie(realm, uriInfo, connection);
}
public static void expireRememberMeCookie(RealmModel realm, UriInfo uriInfo) {
public static void expireRememberMeCookie(RealmModel realm, UriInfo uriInfo, ClientConnection connection) {
logger.debug("Expiring remember me cookie");
String path = getIdentityCookiePath(realm, uriInfo);
String cookieName = KEYCLOAK_REMEMBER_ME;
expireCookie(realm, cookieName, path, true);
expireCookie(realm, cookieName, path, true, connection);
}
protected static String getIdentityCookiePath(RealmModel realm, UriInfo uriInfo) {
@ -153,17 +153,17 @@ public class AuthenticationManager {
return uri.getRawPath();
}
public static void expireCookie(RealmModel realm, String cookieName, String path, boolean httpOnly) {
public static void expireCookie(RealmModel realm, String cookieName, String path, boolean httpOnly, ClientConnection connection) {
logger.debugv("Expiring cookie: {0} path: {1}", cookieName, path);
boolean secureOnly = !realm.isSslNotRequired();
boolean secureOnly = realm.getSslRequired().isRequired(connection);;
CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly);
}
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
return authenticateIdentityCookie(session, realm, uriInfo, headers, true);
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
return authenticateIdentityCookie(session, realm, uriInfo, connection, headers, true);
}
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, boolean checkActive) {
public AuthResult authenticateIdentityCookie(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean checkActive) {
logger.info("authenticateIdentityCookie");
Cookie cookie = headers.getCookies().get(KEYCLOAK_IDENTITY_COOKIE);
if (cookie == null) {
@ -172,16 +172,16 @@ public class AuthenticationManager {
}
String tokenString = cookie.getValue();
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, checkActive, tokenString);
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, checkActive, tokenString);
if (authResult == null) {
expireIdentityCookie(realm, uriInfo);
expireIdentityCookie(realm, uriInfo, connection);
return null;
}
authResult.getSession().setLastSessionRefresh(Time.currentTime());
return authResult;
}
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, boolean checkActive, String tokenString) {
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString) {
try {
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
logger.info("identity token verified");
@ -205,7 +205,7 @@ public class AuthenticationManager {
UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState());
if (!isSessionValid(realm, userSession)) {
if (userSession != null) logout(session, realm, userSession, uriInfo);
if (userSession != null) logout(session, realm, userSession, uriInfo, connection);
logger.info("User session not active");
return null;
}

View file

@ -6,7 +6,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UsernameLoginFailureModel;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import java.util.ArrayList;
import java.util.Collections;

View file

@ -39,7 +39,7 @@ public class OAuthClientManager {
}
}
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
@JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-required",
"resource", "public-client", "credentials"})
public static class InstallationAdapterConfig extends BaseRealmConfig {
@JsonProperty("public-client")
@ -79,7 +79,7 @@ public class OAuthClientManager {
InstallationAdapterConfig rep = new InstallationAdapterConfig();
rep.setRealm(realmModel.getName());
rep.setRealmKey(realmModel.getPublicKeyPem());
rep.setSslNotRequired(realmModel.isSslNotRequired());
rep.setSslRequired(realmModel.getSslRequired().name().toLowerCase());
rep.setAuthServerUrl(baseUri.toString());
if (model.isPublicClient()) rep.setPublicClient(true);

View file

@ -2,6 +2,7 @@ package org.keycloak.services.managers;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.enums.SslRequired;
import org.keycloak.exportimport.util.ImportUtils;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.AdminRoles;
@ -121,6 +122,7 @@ public class RealmManager {
realm.setQuickLoginCheckMilliSeconds(1000);
realm.setMaxDeltaTimeSeconds(60 * 60 * 12); // 12 hours
realm.setFailureFactor(30);
realm.setSslRequired(SslRequired.EXTERNAL);
}
public boolean removeRealm(RealmModel realm) {

View file

@ -1,6 +1,7 @@
package org.keycloak.services.managers;
import org.jboss.logging.Logger;
import org.keycloak.ClientConnection;
import org.keycloak.OAuthErrorException;
import org.keycloak.audit.Audit;
import org.keycloak.audit.Details;
@ -62,7 +63,7 @@ public class TokenManager {
return new AccessCode(realm, clientSession);
}
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException {
JWSInput jws = new JWSInput(encodedRefreshToken);
RefreshToken refreshToken = null;
try {
@ -95,7 +96,7 @@ public class TokenManager {
UserSessionModel userSession = session.sessions().getUserSession(realm, refreshToken.getSessionState());
int currentTime = Time.currentTime();
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
AuthenticationManager.logout(session, realm, userSession, uriInfo, connection);
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session not active", "Session not active");
}

View file

@ -24,6 +24,7 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.ClientConnection;
import org.keycloak.OAuth2Constants;
import org.keycloak.account.AccountPages;
import org.keycloak.account.AccountProvider;
@ -120,6 +121,9 @@ public class AccountService {
@Context
private UriInfo uriInfo;
@Context
private ClientConnection clientConnection;
@Context
private KeycloakSession session;
@ -143,11 +147,11 @@ public class AccountService {
account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo);
boolean passwordUpdateSupported = false;
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, true);
} else {
authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
auth = new Auth(realm, authResult.getToken(), authResult.getUser(), application, false);
}
@ -521,7 +525,7 @@ public class AccountService {
String redirectUri = UriBuilder.fromUri(Urls.accountSocialPage(uriInfo.getBaseUri(), realm.getName())).build().toString();
try {
return Flows.social(realm, uriInfo, provider)
return Flows.social(realm, uriInfo, clientConnection, provider)
.user(user)
.putClientAttribute(OAuth2Constants.CLIENT_ID, Constants.ACCOUNT_MANAGEMENT_APP)
.putClientAttribute(OAuth2Constants.STATE, UUID.randomUUID().toString())

View file

@ -5,14 +5,13 @@ import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.BadRequestException;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.UnauthorizedException;
import org.keycloak.audit.Audit;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.managers.AuditManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.BruteForceProtector;

View file

@ -43,7 +43,7 @@ import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.managers.AccessCode;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.TokenManager;
@ -291,11 +291,11 @@ public class RequiredActionsService {
ClientModel client = realm.findClient(clientId);
if (client == null) {
return Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure(
return Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager).forwardToSecurityFailure(
"Unknown login requester.");
}
if (!client.isEnabled()) {
return Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure(
return Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager).forwardToSecurityFailure(
"Login requester not enabled.");
}
@ -383,14 +383,14 @@ public class RequiredActionsService {
UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectError(accessCode.getClient(), "access_denied", accessCode.getState(), accessCode.getRedirectUri());
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
return Flows.oauth(this.session, realm, request, uriInfo, clientConnection, authManager, tokenManager).redirectError(accessCode.getClient(), "access_denied", accessCode.getState(), accessCode.getRedirectUri());
}
audit.session(userSession);
audit.success();
return Flows.oauth(this.session, realm, request, uriInfo, authManager, tokenManager).redirectAccessCode(accessCode,
return Flows.oauth(this.session, realm, request, uriInfo, clientConnection, authManager, tokenManager).redirectAccessCode(accessCode,
userSession, accessCode.getState(), accessCode.getRedirectUri());
}
}

View file

@ -39,7 +39,7 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.managers.AuditManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.RealmManager;
@ -127,7 +127,7 @@ public class SocialResource {
.detail(Details.AUTH_METHOD, authMethod);
AuthenticationManager authManager = new AuthenticationManager();
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!realm.isEnabled()) {
audit.error(Errors.REALM_DISABLED);
@ -300,7 +300,7 @@ public class SocialResource {
}
try {
return Flows.social(realm, uriInfo, provider)
return Flows.social(realm, uriInfo, clientConnection, provider)
.putClientAttribute(OAuth2Constants.CLIENT_ID, clientId)
.putClientAttribute(OAuth2Constants.SCOPE, scope)
.putClientAttribute(OAuth2Constants.STATE, state)

View file

@ -34,7 +34,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.managers.AccessCode;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
@ -433,7 +433,7 @@ public class TokenService {
String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN);
AccessToken accessToken;
try {
accessToken = tokenManager.refreshAccessToken(session, uriInfo, realm, client, refreshToken, audit);
accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, audit);
} catch (OAuthErrorException e) {
Map<String, String> error = new HashMap<String, String>();
error.put(OAuth2Constants.ERROR, e.getError());
@ -487,7 +487,7 @@ public class TokenService {
audit.detail(Details.REMEMBER_ME, "true");
}
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!checkSsl()) {
return oauth.forwardToSecurityFailure("HTTPS required");
@ -521,9 +521,9 @@ public class TokenService {
AuthenticationStatus status = authManager.authenticateForm(session, clientConnection, realm, formData);
if (remember) {
authManager.createRememberMeCookie(realm, uriInfo);
authManager.createRememberMeCookie(realm, uriInfo, clientConnection);
} else {
authManager.expireRememberMeCookie(realm, uriInfo);
authManager.expireRememberMeCookie(realm, uriInfo, clientConnection);
}
UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username);
@ -591,7 +591,7 @@ public class TokenService {
.detail(Details.EMAIL, email)
.detail(Details.REGISTER_METHOD, "form");
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!realm.isEnabled()) {
logger.warn("Realm not enabled");
@ -793,7 +793,7 @@ public class TokenService {
UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState());
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
Map<String, String> res = new HashMap<String, String>();
res.put(OAuth2Constants.ERROR, "invalid_grant");
res.put(OAuth2Constants.ERROR_DESCRIPTION, "Session not active");
@ -911,7 +911,7 @@ public class TokenService {
audit.event(EventType.LOGIN).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!checkSsl()) {
return oauth.forwardToSecurityFailure("HTTPS required");
@ -949,7 +949,7 @@ public class TokenService {
}
logger.info("Checking cookie...");
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers);
if (authResult != null) {
UserModel user = authResult.getUser();
UserSessionModel session = authResult.getSession();
@ -994,7 +994,7 @@ public class TokenService {
audit.event(EventType.REGISTER).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!checkSsl()) {
return oauth.forwardToSecurityFailure("HTTPS required");
@ -1030,7 +1030,7 @@ public class TokenService {
return oauth.forwardToSecurityFailure("Registration not allowed");
}
authManager.expireIdentityCookie(realm, uriInfo);
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
return Flows.forms(session, realm, uriInfo).createRegistration();
}
@ -1057,7 +1057,7 @@ public class TokenService {
}
// authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, headers, false);
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers, false);
if (authResult != null) {
logout(authResult.getSession());
} else if (sessionState != null) {
@ -1080,7 +1080,7 @@ public class TokenService {
}
private void logout(UserSessionModel userSession) {
authManager.logout(session, realm, userSession, uriInfo);
authManager.logout(session, realm, userSession, uriInfo, clientConnection);
audit.user(userSession.getUser()).session(userSession).success();
}
@ -1096,7 +1096,7 @@ public class TokenService {
public Response processOAuth(final MultivaluedMap<String, String> formData) {
audit.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code");
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, authManager, tokenManager);
OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
if (!checkSsl()) {
return oauth.forwardToSecurityFailure("HTTPS required");
@ -1129,7 +1129,7 @@ public class TokenService {
}
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
AuthenticationManager.logout(session, realm, userSession, uriInfo);
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
audit.error(Errors.INVALID_CODE);
return oauth.forwardToSecurityFailure("Session not active");
}
@ -1245,7 +1245,11 @@ public class TokenService {
}
private boolean checkSsl() {
return realm.isSslNotRequired() || uriInfo.getBaseUri().getScheme().equals("https");
if (uriInfo.getBaseUri().getScheme().equals("https")) {
return true;
} else {
return !realm.getSslRequired().isRequired(clientConnection);
}
}
private Response createError(String error, String errorDescription, Response.Status status) {

View file

@ -6,6 +6,7 @@ import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.ClientConnection;
import org.keycloak.Config;
import org.keycloak.freemarker.Theme;
import org.keycloak.freemarker.ThemeProvider;
@ -54,6 +55,9 @@ public class AdminConsole {
@Context
protected UriInfo uriInfo;
@Context
protected ClientConnection clientConnection;
@Context
protected HttpRequest request;
@ -174,7 +178,7 @@ public class AdminConsole {
@NoCache
public Response whoAmI(final @Context HttpHeaders headers) {
RealmManager realmManager = new RealmManager(session);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers);
if (authResult == null) {
return Response.status(401).build();
}

View file

@ -6,6 +6,7 @@ import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.UnauthorizedException;
import org.keycloak.ClientConnection;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
@ -41,6 +42,9 @@ public class AdminRoot {
@Context
protected UriInfo uriInfo;
@Context
protected ClientConnection clientConnection;
@Context
protected HttpRequest request;
@ -142,7 +146,7 @@ public class AdminRoot {
if (realm == null) {
throw new UnauthorizedException("Unknown realm in token");
}
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, headers);
AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers);
if (authResult == null) {
logger.debug("Token not valid");
throw new UnauthorizedException("Bearer");

View file

@ -22,6 +22,7 @@
package org.keycloak.services.resources.flows;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.ClientConnection;
import org.keycloak.login.LoginFormsProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@ -43,13 +44,13 @@ public class Flows {
return session.getProvider(LoginFormsProvider.class).setRealm(realm).setUriInfo(uriInfo);
}
public static OAuthFlows oauth(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo, AuthenticationManager authManager,
public static OAuthFlows oauth(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo, ClientConnection clientConnection, AuthenticationManager authManager,
TokenManager tokenManager) {
return new OAuthFlows(session, realm, request, uriInfo, authManager, tokenManager);
return new OAuthFlows(session, realm, request, uriInfo, clientConnection, authManager, tokenManager);
}
public static SocialRedirectFlows social(RealmModel realm, UriInfo uriInfo, SocialProvider provider) {
return new SocialRedirectFlows(realm, uriInfo, provider);
public static SocialRedirectFlows social(RealmModel realm, UriInfo uriInfo, ClientConnection clientConnection, SocialProvider provider) {
return new SocialRedirectFlows(realm, uriInfo, clientConnection, provider);
}
public static ErrorFlows errors() {

View file

@ -24,6 +24,7 @@ package org.keycloak.services.resources.flows;
import org.jboss.logging.Logger;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.ClientConnection;
import org.keycloak.OAuth2Constants;
import org.keycloak.audit.Audit;
import org.keycloak.audit.Details;
@ -68,16 +69,18 @@ public class OAuthFlows {
private final UriInfo uriInfo;
private ClientConnection clientConnection;
private final AuthenticationManager authManager;
private final TokenManager tokenManager;
OAuthFlows(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo, AuthenticationManager authManager,
OAuthFlows(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo, ClientConnection clientConnection, AuthenticationManager authManager,
TokenManager tokenManager) {
this.session = session;
this.realm = realm;
this.request = request;
this.uriInfo = uriInfo;
this.clientConnection = clientConnection;
this.authManager = authManager;
this.tokenManager = tokenManager;
}
@ -104,8 +107,8 @@ public class OAuthFlows {
}
// refresh the cookies!
authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo);
if (userSession.isRememberMe()) authManager.createRememberMeCookie(realm, uriInfo);
authManager.createLoginCookie(realm, accessCode.getUser(), userSession, uriInfo, clientConnection);
if (userSession.isRememberMe()) authManager.createRememberMeCookie(realm, uriInfo, clientConnection);
return location.build();
}

View file

@ -1,5 +1,6 @@
package org.keycloak.services.resources.flows;
import org.keycloak.ClientConnection;
import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
@ -20,12 +21,14 @@ public class SocialRedirectFlows {
private final RealmModel realm;
private final UriInfo uriInfo;
private ClientConnection clientConnection;
private final SocialProvider socialProvider;
private final SocialResource.State state;
SocialRedirectFlows(RealmModel realm, UriInfo uriInfo, SocialProvider provider) {
SocialRedirectFlows(RealmModel realm, UriInfo uriInfo, ClientConnection clientConnection, SocialProvider provider) {
this.realm = realm;
this.uriInfo = uriInfo;
this.clientConnection = clientConnection;
this.socialProvider = provider;
state = new SocialResource.State();
@ -62,7 +65,7 @@ public class SocialRedirectFlows {
.jsonContent(authRequest.getAttributes())
.rsa256(realm.getPrivateKey());
CookieHelper.addCookie("KEYCLOAK_SOCIAL", encoded, cookiePath, null, null, -1, !realm.isSslNotRequired(), true);
CookieHelper.addCookie("KEYCLOAK_SOCIAL", encoded, cookiePath, null, null, -1, realm.getSslRequired().isRequired(clientConnection), true);
}
return Response.status(302).location(authRequest.getAuthUri()).build();

View file

@ -243,7 +243,7 @@ public class AdminAPITest {
if (rep.isResetPasswordAllowed() != null) Assert.assertEquals(rep.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
if (rep.isUpdateProfileOnInitialSocialLogin() != null)
Assert.assertEquals(rep.isUpdateProfileOnInitialSocialLogin(), storedRealm.isUpdateProfileOnInitialSocialLogin());
if (rep.isSslNotRequired() != null) Assert.assertEquals(rep.isSslNotRequired(), storedRealm.isSslNotRequired());
if (rep.getSslRequired() != null) Assert.assertEquals(rep.getSslRequired(), storedRealm.getSslRequired());
if (rep.getAccessCodeLifespan() != null) Assert.assertEquals(rep.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
if (rep.getAccessCodeLifespanUserAction() != null)
Assert.assertEquals(rep.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());

View file

@ -26,6 +26,7 @@ import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.KeycloakSession;
@ -67,7 +68,7 @@ public class CompositeRoleTest {
realm.setSsoSessionMaxLifespan(10000);
realm.setAccessCodeLifespanUserAction(1000);
realm.setAccessCodeLifespan(1000);
realm.setSslNotRequired(true);
realm.setSslRequired(SslRequired.EXTERNAL);
realm.setEnabled(true);
realm.addRequiredCredential(UserCredentialModel.PASSWORD);
realm.setAuthenticationProviders(Arrays.asList(AuthenticationProviderModel.DEFAULT_PROVIDER));

View file

@ -2,10 +2,8 @@ package org.keycloak.testsuite.model;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.RealmModel;
@ -14,7 +12,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.ClientConnection;
import org.keycloak.ClientConnection;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
import org.keycloak.services.managers.BruteForceProtector;

View file

@ -2,6 +2,7 @@ package org.keycloak.testsuite.model;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.enums.SslRequired;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.ModelToRepresentation;
@ -17,7 +18,7 @@ public class ModelTest extends AbstractModelTest {
realm.setRegistrationAllowed(true);
realm.setResetPasswordAllowed(true);
realm.setSocial(true);
realm.setSslNotRequired(true);
realm.setSslRequired(SslRequired.EXTERNAL);
realm.setVerifyEmail(true);
realm.setAccessTokenLifespan(1000);
realm.setPasswordPolicy(new PasswordPolicy("length"));
@ -50,7 +51,7 @@ public class ModelTest extends AbstractModelTest {
Assert.assertEquals(expected.isRegistrationAllowed(), actual.isRegistrationAllowed());
Assert.assertEquals(expected.isResetPasswordAllowed(), actual.isResetPasswordAllowed());
Assert.assertEquals(expected.isSocial(), actual.isSocial());
Assert.assertEquals(expected.isSslNotRequired(), actual.isSslNotRequired());
Assert.assertEquals(expected.getSslRequired(), actual.getSslRequired());
Assert.assertEquals(expected.isVerifyEmail(), actual.isVerifyEmail());
Assert.assertEquals(expected.getAccessTokenLifespan(), actual.getAccessTokenLifespan());

View file

@ -2,7 +2,7 @@
"realm": "demo",
"resource": "customer-portal",
"auth-server-url": "/auth",
"ssl-not-required": true,
"ssl-required" : "external",
"credentials": {
"secret": "password"
}

View file

@ -3,7 +3,7 @@
"resource": "customer-portal",
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url": "http://localhost:8081/auth",
"ssl-not-required": true,
"ssl-required" : "external",
"expose-token": true,
"credentials": {
"secret": "password"

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"auth-server-url": "/auth",
"ssl-not-required": true,
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"resource" : "customer-db",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"ssl-not-required" : true,
"ssl-required" : "external",
"bearer-only" : true,
"enable-cors" : true

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"updateProfileOnInitialSocialLogin": false,

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"passwordCredentialGrantAllowed": true,

View file

@ -2,7 +2,7 @@
"realm" : "demo",
"resource" : "product-portal",
"auth-server-url" : "/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"credentials" : {
"secret": "password"
}

View file

@ -3,7 +3,7 @@
"resource" : "product-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://localhost:8081/auth",
"ssl-not-required" : true,
"ssl-required" : "external",
"credentials" : {
"secret": "password"
}

View file

@ -1,7 +1,7 @@
{
"realm": "admin-test-1",
"enabled": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
@ -95,4 +95,4 @@
}
]
}
}
}

View file

@ -5,7 +5,7 @@
"accessTokenLifespan": 600,
"accessCodeLifespan": 600,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
@ -184,4 +184,4 @@
}
]
}
}
}

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 300,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"sslRequired": "external",
"updateProfileOnInitialSocialLogin": false,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",

View file

@ -4,7 +4,7 @@
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": false,
"social": false,
"updateProfileOnInitialSocialLogin": false,

View file

@ -5,7 +5,7 @@
"accessTokenLifespan": 600,
"accessCodeLifespan": 600,
"accessCodeLifespanUserAction": 600,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
@ -196,4 +196,4 @@
}
]
}
}
}

View file

@ -2,7 +2,7 @@
"id": "test",
"realm": "test",
"enabled": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"passwordCredentialGrantAllowed": true,
@ -97,4 +97,4 @@
}
]
}
}
}

View file

@ -2,7 +2,7 @@
"id": "perf-realm",
"realm": "perf-realm",
"enabled": true,
"sslNotRequired": true,
"sslRequired": "external",
"registrationAllowed": true,
"resetPasswordAllowed": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
@ -109,4 +109,4 @@
}
]
}
}
}