<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.E-mailStijl17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1056515100;
        mso-list-type:hybrid;
        mso-list-template-ids:-1484220350 68354063 68354073 68354075 68354063 68354073 68354075 68354063 68354073 68354075;}
@list l0:level1
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=NL link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span lang=EN-US>Hi everybody,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Quick intro: I’m part of a development team in The Netherlands that is building a company-wide SSO solution. We’ve chosen KeyCloak to realize this and will use OpenID Connect to secure our REST services. It’s a great product and seems to be the only one having both support for all kinds of security standards and a model and GUI for users and roles. Thanks for creating it! </span><span lang=EN-US style='font-family:Wingdings'>J</span><span lang=EN-US><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>(if this should be asked instead on the users mailing list, please correct me and I’ll post it there)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>So far, so good, but we have some extra requirements that do not fit into the base KeyCloak data model. See below for details if you’re interested. My question is: what is the preferred way / best practice to extend the functionality of KeyCloak while keeping the impact on the original sources to a minimum? Of course we could just fork the most recent version and start hacking away, but we’d like to be able to upgrade to newer versions of KeyCloak without too much hassle. Possibilities that we’ve come up with so far:<o:p></o:p></span></p><p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span lang=EN-US><span style='mso-list:Ignore'>1.<span style='font:7.0pt "Times New Roman"'> </span></span></span><![endif]><span lang=EN-US>Create completely separate modules that will extend the functionality the way we need.<o:p></o:p></span></p><p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span lang=EN-US><span style='mso-list:Ignore'>2.<span style='font:7.0pt "Times New Roman"'> </span></span></span><![endif]><span lang=EN-US>Fork on Github, apply custom changes, and try to merge in updates from the master / release branches / tags<o:p></o:p></span></p><p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span lang=EN-US><span style='mso-list:Ignore'>3.<span style='font:7.0pt "Times New Roman"'> </span></span></span><![endif]><span lang=EN-US>Apply custom changes on KeyCloak artifacts using a Maven plugin, such as Truezip (http://www.mojohaus.org/truezip/truezip-maven-plugin/index.html) - manipulate zip files by adding/removing/replacing or Shade (http://maven.apache.org/plugins/maven-shade-plugin/) - combine multiple jars to 1 'uber-jar' containing the contents of both and when overlapping decide on conflicts through configuration.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Of course number 1 is preferred, but I do not see how to add custom mappers or JPA entities without making changes in the original module files. The other options seem like valid alternatives, but maybe there is better / standard way to do this. So any help / insight / shared experience on this is much appreciated, thanks!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Kind regards,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Erik Mulder<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Senior Software Engineer<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Docdata Payments – NL<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>P.S. Details on why we want to extend the KeyCloak data model: (any feedback on the contents of this P.S. is also welcome!)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Our clients are merchants that have several webshops. We manage their online payments (shopping cart checkout). We want to be able to let a merchant manage their own users and let a user have different roles for different webshops within the same merchant. The overall possible roles are fixed though, no specific roles per merchant. We could create a separate realm for every merchant, but then we need to duplicate all roles every time. Furthermore, in KeyCloak there is no concept of a role within a certain context. This is very understandable, since every situation has it’s own requirements. We did a proof of concept by adding tables and entities for Merchant, UserMerchant, UserMerchantRole etc. and adding a custom mapper that can put this information on the Access token. Worked like a charm! But it does need some changes in the KeyCloak modules and sources to work, hence the question above.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div></body></html>