11package org .springframework .security .oauth2 .provider .endpoint ;
22
3- import java .util .Map ;
4-
5- import javax .servlet .http .HttpServletRequest ;
6-
3+ import org .springframework .security .oauth2 .provider .AuthorizationRequest ;
4+ import org .springframework .security .web .csrf .CsrfToken ;
75import org .springframework .web .bind .annotation .RequestMapping ;
86import org .springframework .web .bind .annotation .SessionAttributes ;
97import org .springframework .web .servlet .ModelAndView ;
8+ import org .springframework .web .servlet .View ;
9+ import org .springframework .web .servlet .support .ServletUriComponentsBuilder ;
10+ import org .springframework .web .util .HtmlUtils ;
11+
12+ import javax .servlet .http .HttpServletRequest ;
13+ import javax .servlet .http .HttpServletResponse ;
14+ import java .util .Map ;
1015
1116/**
1217 * Controller for displaying the approval page for the authorization server.
@@ -19,56 +24,91 @@ public class WhitelabelApprovalEndpoint {
1924
2025 @ RequestMapping ("/oauth/confirm_access" )
2126 public ModelAndView getAccessConfirmation (Map <String , Object > model , HttpServletRequest request ) throws Exception {
22- String template = createTemplate (model , request );
27+ final String approvalContent = createTemplate (model , request );
2328 if (request .getAttribute ("_csrf" ) != null ) {
2429 model .put ("_csrf" , request .getAttribute ("_csrf" ));
2530 }
26- return new ModelAndView (new SpelView (template ), model );
31+ View approvalView = new View () {
32+ @ Override
33+ public String getContentType () {
34+ return "text/html" ;
35+ }
36+
37+ @ Override
38+ public void render (Map <String , ?> model , HttpServletRequest request , HttpServletResponse response ) throws Exception {
39+ response .setContentType (getContentType ());
40+ response .getWriter ().append (approvalContent );
41+ }
42+ };
43+ return new ModelAndView (approvalView , model );
2744 }
2845
2946 protected String createTemplate (Map <String , Object > model , HttpServletRequest request ) {
30- String template = TEMPLATE ;
31- if (model .containsKey ("scopes" ) || request .getAttribute ("scopes" ) != null ) {
32- template = template .replace ("%scopes%" , createScopes (model , request )).replace ("%denial%" , "" );
47+ AuthorizationRequest authorizationRequest = (AuthorizationRequest ) model .get ("authorizationRequest" );
48+ String clientId = authorizationRequest .getClientId ();
49+
50+ StringBuilder builder = new StringBuilder ();
51+ builder .append ("<html><body><h1>OAuth Approval</h1>" );
52+ builder .append ("<p>Do you authorize \" " ).append (HtmlUtils .htmlEscape (clientId ));
53+ builder .append ("\" to access your protected resources?</p>" );
54+ builder .append ("<form id=\" confirmationForm\" name=\" confirmationForm\" action=\" " );
55+
56+ String requestPath = ServletUriComponentsBuilder .fromContextPath (request ).build ().getPath ();
57+ if (requestPath == null ) {
58+ requestPath = "" ;
3359 }
34- else {
35- template = template .replace ("%scopes%" , "" ).replace ("%denial%" , DENIAL );
60+
61+ builder .append (requestPath ).append ("/oauth/authorize\" method=\" post\" >" );
62+ builder .append ("<input name=\" user_oauth_approval\" value=\" true\" type=\" hidden\" />" );
63+
64+ String csrfTemplate = null ;
65+ CsrfToken csrfToken = (CsrfToken ) (model .containsKey ("_csrf" ) ? model .get ("_csrf" ) : request .getAttribute ("_csrf" ));
66+ if (csrfToken != null ) {
67+ csrfTemplate = "<input type=\" hidden\" name=\" " + HtmlUtils .htmlEscape (csrfToken .getParameterName ()) +
68+ "\" value=\" " + HtmlUtils .htmlEscape (csrfToken .getToken ()) + "\" />" ;
3669 }
37- if (model . containsKey ( "_csrf" ) || request . getAttribute ( "_csrf" ) != null ) {
38- template = template . replace ( "%csrf%" , CSRF );
70+ if (csrfTemplate != null ) {
71+ builder . append ( csrfTemplate );
3972 }
40- else {
41- template = template .replace ("%csrf%" , "" );
73+
74+ String authorizeInputTemplate = "<label><input name=\" authorize\" value=\" Authorize\" type=\" submit\" /></label></form>" ;
75+
76+ if (model .containsKey ("scopes" ) || request .getAttribute ("scopes" ) != null ) {
77+ builder .append (createScopes (model , request ));
78+ builder .append (authorizeInputTemplate );
79+ } else {
80+ builder .append (authorizeInputTemplate );
81+ builder .append ("<form id=\" denialForm\" name=\" denialForm\" action=\" " );
82+ builder .append (requestPath ).append ("/oauth/authorize\" method=\" post\" >" );
83+ builder .append ("<input name=\" user_oauth_approval\" value=\" false\" type=\" hidden\" />" );
84+ if (csrfTemplate != null ) {
85+ builder .append (csrfTemplate );
86+ }
87+ builder .append ("<label><input name=\" deny\" value=\" Deny\" type=\" submit\" /></label></form>" );
4288 }
43- return template ;
89+
90+ builder .append ("</body></html>" );
91+
92+ return builder .toString ();
4493 }
4594
4695 private CharSequence createScopes (Map <String , Object > model , HttpServletRequest request ) {
4796 StringBuilder builder = new StringBuilder ("<ul>" );
4897 @ SuppressWarnings ("unchecked" )
49- Map <String , String > scopes = (Map <String , String >) (model .containsKey ("scopes" ) ? model . get ( "scopes" ) : request
50- .getAttribute ("scopes" ));
98+ Map <String , String > scopes = (Map <String , String >) (model .containsKey ("scopes" ) ?
99+ model . get ( "scopes" ) : request .getAttribute ("scopes" ));
51100 for (String scope : scopes .keySet ()) {
52101 String approved = "true" .equals (scopes .get (scope )) ? " checked" : "" ;
53102 String denied = !"true" .equals (scopes .get (scope )) ? " checked" : "" ;
54- String value = SCOPE .replace ("%scope%" , scope ).replace ("%key%" , scope ).replace ("%approved%" , approved )
55- .replace ("%denied%" , denied );
56- builder .append (value );
103+ scope = HtmlUtils .htmlEscape (scope );
104+
105+ builder .append ("<li><div class=\" form-group\" >" );
106+ builder .append (scope ).append (": <input type=\" radio\" name=\" " );
107+ builder .append (scope ).append ("\" value=\" true\" " ).append (approved ).append (">Approve</input> " );
108+ builder .append ("<input type=\" radio\" name=\" " ).append (scope ).append ("\" value=\" false\" " );
109+ builder .append (denied ).append (">Deny</input></div></li>" );
57110 }
58111 builder .append ("</ul>" );
59112 return builder .toString ();
60113 }
61-
62- private static String CSRF = "<input type='hidden' name='${_csrf.parameterName}' value='${_csrf.token}' />" ;
63-
64- private static String DENIAL = "<form id='denialForm' name='denialForm' action='${path}/oauth/authorize' method='post'><input name='user_oauth_approval' value='false' type='hidden'/>%csrf%<label><input name='deny' value='Deny' type='submit'/></label></form>" ;
65-
66- private static String TEMPLATE = "<html><body><h1>OAuth Approval</h1>"
67- + "<p>Do you authorize '${authorizationRequest.clientId}' to access your protected resources?</p>"
68- + "<form id='confirmationForm' name='confirmationForm' action='${path}/oauth/authorize' method='post'><input name='user_oauth_approval' value='true' type='hidden'/>%csrf%%scopes%<label><input name='authorize' value='Authorize' type='submit'/></label></form>"
69- + "%denial%</body></html>" ;
70-
71- private static String SCOPE = "<li><div class='form-group'>%scope%: <input type='radio' name='%key%'"
72- + " value='true'%approved%>Approve</input> <input type='radio' name='%key%' value='false'%denied%>Deny</input></div></li>" ;
73-
74- }
114+ }
0 commit comments