Browse Source

CAS REST FIX

Crystal.Sea 4 years ago
parent
commit
4c86d6860d

+ 118 - 6
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasRestV1Endpoint.java

@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.maxkey.authn.BasicAuthentication;
 import org.maxkey.authn.realm.AbstractAuthenticationRealm;
+import org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder;
 import org.maxkey.authz.cas.endpoint.ticket.CasConstants;
 import org.maxkey.authz.cas.endpoint.ticket.ServiceTicketImpl;
 import org.maxkey.authz.cas.endpoint.ticket.TicketGrantingTicketImpl;
@@ -57,7 +58,7 @@ import org.springframework.web.bind.annotation.RequestParam;
  */
 @Controller
 public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
-	final static Logger _logger = LoggerFactory.getLogger(CasRestV1Endpoint.class);
+    final static Logger _logger = LoggerFactory.getLogger(CasRestV1Endpoint.class);
 	
 	@Autowired
     protected PasswordPolicyValidator passwordPolicyValidator;
@@ -73,7 +74,6 @@ public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
     public ResponseEntity<String> casLoginRestTickets(
             HttpServletRequest request,
             HttpServletResponse response,
-           
             @RequestParam(value=CasConstants.PARAMETER.SERVICE,required=false) String casService,
             @RequestParam(value=CasConstants.PARAMETER.REST_USERNAME,required=true) String username,
             @RequestParam(value=CasConstants.PARAMETER.REST_PASSWORD,required=true) String password){
@@ -133,10 +133,10 @@ public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
         }
 	}
 	
-	   @RequestMapping(value="/authz/cas/v1/tickets/{ticketGrantingTicket}", 
+	@RequestMapping(value="/authz/cas/v1/tickets/{ticketGrantingTicket}", 
 	            method=RequestMethod.POST, 
 	            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
-	    public ResponseEntity<String> requestServiceTicket(
+    public ResponseEntity<String> requestServiceTicket(
 	            HttpServletRequest request,
 	            HttpServletResponse response,
 	            @PathVariable("ticketGrantingTicket") String ticketGrantingTicket,
@@ -168,6 +168,46 @@ public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
         }
 	       return new ResponseEntity<>("", HttpStatus.BAD_REQUEST);
 	   }
+	   
+    @RequestMapping(value="/authz/cas/v1/tickets/{ticketGrantingTicket}", 
+	            method=RequestMethod.GET)
+    public ResponseEntity<String> verifyTicketGrantingTicketStatus(
+	            @PathVariable("ticketGrantingTicket") String ticketGrantingTicket,
+	            HttpServletRequest request,
+	            HttpServletResponse response){
+	       try {
+            TicketGrantingTicketImpl ticketGrantingTicketImpl = 
+                       (TicketGrantingTicketImpl) ticketServices.consumeTicket(ticketGrantingTicket);
+                if(ticketGrantingTicketImpl != null) {
+                    return new ResponseEntity<>("", HttpStatus.OK);
+                }
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+	       return new ResponseEntity<>("", HttpStatus.NOT_FOUND);
+	}
+    
+    @RequestMapping(value="/authz/cas/v1/tickets/{ticketGrantingTicket}", 
+            method=RequestMethod.DELETE)
+    public ResponseEntity<String> destroyTicketGrantingTicket(
+            @PathVariable("ticketGrantingTicket") String ticketGrantingTicket,
+            HttpServletRequest request,
+            HttpServletResponse response){
+       try {
+        TicketGrantingTicketImpl ticketGrantingTicketImpl = 
+                   (TicketGrantingTicketImpl) ticketServices.consumeTicket(ticketGrantingTicket);
+            if(ticketGrantingTicketImpl != null) {
+                return new ResponseEntity<>("", HttpStatus.OK);
+            }
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+       return new ResponseEntity<>("", HttpStatus.NOT_FOUND);
+    }
+	   
+	   
 	@RequestMapping(value="/authz/cas/v1/users", 
             method=RequestMethod.POST, 
             consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@@ -177,8 +217,80 @@ public class CasRestV1Endpoint  extends CasBaseAuthorizeEndpoint{
             @RequestParam(value=CasConstants.PARAMETER.SERVICE,required=false) String casService,
             @RequestParam(value=CasConstants.PARAMETER.REST_USERNAME,required=true) String username,
             @RequestParam(value=CasConstants.PARAMETER.REST_PASSWORD,required=true) String password){
-        
-       return null;
+	    try {
+            if (password == null || password.isEmpty()) {
+                throw new BadCredentialsException("No credentials are provided or extracted to authenticate the REST request");
+            }
+            
+            AbstractAuthenticationRealm authenticationRealm = 
+                    (AbstractAuthenticationRealm) WebContext.getBean("authenticationRealm");
+            UserInfo loadeduserInfo = authenticationRealm.loadUserInfo(username, "");
+            if (loadeduserInfo != null) {
+                
+                authenticationRealm.passwordMatches(loadeduserInfo, password);
+                
+                passwordPolicyValidator.passwordPolicyValid(loadeduserInfo);
+                
+                WebContext.setUserInfo(loadeduserInfo);
+                BasicAuthentication authentication =new BasicAuthentication();
+                authentication.setUsername(username);
+                authentication.setPassword(password);
+                authentication.setAuthType("basic");
+                
+                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
+                        new UsernamePasswordAuthenticationToken(
+                                authentication, 
+                                "PASSWORD", 
+                                authenticationRealm.grantAuthority(loadeduserInfo)
+                        );
+
+                authentication.setAuthenticated(true);
+                WebContext.setAuthentication(usernamePasswordAuthenticationToken);
+                WebContext.setUserInfo(loadeduserInfo);
+
+                authenticationRealm.insertLoginHistory(loadeduserInfo, "CAS", "", "", "SUCCESS");
+                
+                TicketGrantingTicketImpl ticketGrantingTicket=new TicketGrantingTicketImpl("Random",WebContext.getAuthentication(),null);
+                
+                String ticket=ticketServices.createTicket(ticketGrantingTicket);
+                String location = applicationConfig.getServerPrefix()+"/authz/cas/v1/tickets/" + ticket;
+                HttpHeaders headers = new HttpHeaders();
+                headers.add("location", location);
+                ServiceResponseBuilder serviceResponseBuilder=new ServiceResponseBuilder();
+                serviceResponseBuilder.setFormat(CasConstants.FORMAT_TYPE.JSON);
+                //for user
+                serviceResponseBuilder.setAttribute("uid", loadeduserInfo.getId());
+                serviceResponseBuilder.setAttribute("displayName",loadeduserInfo.getDisplayName());
+                serviceResponseBuilder.setAttribute("firstName", loadeduserInfo.getGivenName());
+                serviceResponseBuilder.setAttribute("lastname", loadeduserInfo.getFamilyName());
+                serviceResponseBuilder.setAttribute("mobile", loadeduserInfo.getMobile());
+                serviceResponseBuilder.setAttribute("birthday", loadeduserInfo.getBirthDate());
+                serviceResponseBuilder.setAttribute("gender", loadeduserInfo.getGender()+"");
+                
+                //for work
+                serviceResponseBuilder.setAttribute("employeeNumber", loadeduserInfo.getEmployeeNumber());
+                serviceResponseBuilder.setAttribute("title", loadeduserInfo.getJobTitle());
+                serviceResponseBuilder.setAttribute("email", loadeduserInfo.getWorkEmail());
+                serviceResponseBuilder.setAttribute("department", loadeduserInfo.getDepartment());
+                serviceResponseBuilder.setAttribute("departmentId", loadeduserInfo.getDepartmentId());
+                serviceResponseBuilder.setAttribute("workRegion",loadeduserInfo.getWorkRegion());
+                
+                serviceResponseBuilder.success().setUser(loadeduserInfo.getUsername());
+                return new ResponseEntity<>(serviceResponseBuilder.serviceResponseBuilder(), headers ,HttpStatus.OK);
+                
+            }else {
+                String message = WebContext.getI18nValue("login.error.username");
+                _logger.debug("login user  " + username + " not in this System ." + message);
+                throw new BadCredentialsException(WebContext.getI18nValue("login.error.username"));
+            }
+        } catch (final AuthenticationException e) {
+            _logger.error("BadCredentialsException ", e);
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
+        } catch (final Exception e) {
+            
+            _logger.error("Exception ", e);
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
     }
 	
 }

+ 172 - 0
maxkey-protocols/maxkey-protocol-cas/src/test/java/org/maxkey/web/authorize/endpoint/Client.java

@@ -0,0 +1,172 @@
+package org.maxkey.web.authorize.endpoint;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+
+public class Client {
+    
+    public static String getTicket(final String server, final String username, final String password,
+            final String service) {
+        notNull(server, "server must not be null");
+        notNull(username, "username must not be null");
+        notNull(password, "password must not be null");
+        notNull(service, "service must not be null");
+ 
+        return getServiceTicket(server, getTicketGrantingTicket(server, username, password), service);
+    }
+ 
+    /**
+     * 取得ST
+     * @param server
+     * @param ticketGrantingTicket
+     * @param service
+     */
+    private static String getServiceTicket(final String server, final String ticketGrantingTicket, final String service) {
+        if (ticketGrantingTicket == null)
+            return null;
+ 
+        final HttpClient client = new HttpClient();
+ 
+        final PostMethod post = new PostMethod(server + "/" + ticketGrantingTicket);
+ 
+        post.setRequestBody(new NameValuePair[] { new NameValuePair("service", service) });
+ 
+        try {
+            client.executeMethod(post);
+ 
+            final String response = post.getResponseBodyAsString();
+ 
+            switch (post.getStatusCode()) {
+            case 200:
+                return response;
+ 
+            default:
+                warning("Invalid response code (" + post.getStatusCode() + ") from CAS server!");
+                info("Response (1k): " + response.substring(0, Math.min(1024, response.length())));
+                break;
+            }
+        }
+ 
+        catch (final IOException e) {
+            warning(e.getMessage());
+        }
+ 
+        finally {
+            post.releaseConnection();
+        }
+ 
+        return null;
+    }
+ 
+    /**
+     * @param server
+     * @param username
+     * @param password
+     */
+    private static String getTicketGrantingTicket(final String server, final String username, final String password) {
+        final HttpClient client = new HttpClient();
+ 
+        final PostMethod post = new PostMethod(server);
+ 
+        post.setRequestBody(new NameValuePair[] { new NameValuePair("username", username),
+                new NameValuePair("password", password) });
+ 
+        try {
+            client.executeMethod(post);
+ 
+            final String response = post.getResponseBodyAsString();
+            info("TGT="+response);
+            switch (post.getStatusCode()) {
+            case 201: {
+                final Matcher matcher = Pattern.compile(".*action=\".*/(.*?)\".*").matcher(response);
+ 
+                if (matcher.matches())
+                    return matcher.group(1);
+ 
+                warning("Successful ticket granting request, but no ticket found!");
+                info("Response (1k): " + response.substring(0, Math.min(1024, response.length())));
+                break;
+            }
+ 
+            default:
+                warning("Invalid response code (" + post.getStatusCode() + ") from CAS server!");
+                info("Response (1k): " + response.substring(0, Math.min(1024, response.length())));
+                break;
+            }
+        }
+ 
+        catch (final IOException e) {
+            warning(e.getMessage());
+        }
+ 
+        finally {
+            post.releaseConnection();
+        }
+ 
+        return null;
+    }
+ 
+    private static void ticketValidate(String serverValidate, String serviceTicket, String service) {
+        notNull(serviceTicket, "paramter 'serviceTicket' is not null");
+        notNull(service, "paramter 'service' is not null");
+ 
+        final HttpClient client = new HttpClient();
+        GetMethod post = null;
+ 
+        try {
+            post = new GetMethod(serverValidate+"?"+"ticket="+serviceTicket+"&service="+URLEncoder.encode(service, "UTF-8"));
+            client.executeMethod(post);
+ 
+            final String response = post.getResponseBodyAsString();
+            info(response);
+            switch (post.getStatusCode()) {
+            case 200: {
+                info("成功取得用户数据");
+            }
+            default: {
+ 
+            }
+            }
+ 
+        } catch (Exception e) {
+            warning(e.getMessage());
+        } finally {
+            //释放资源
+            post.releaseConnection();
+        }
+ 
+    }
+ 
+    private static void notNull(final Object object, final String message) {
+        if (object == null)
+            throw new IllegalArgumentException(message);
+    }
+ 
+    public static void main(final String[] args) throws Exception {
+        final String server = "https://sso.maxkey.top/maxkey/authz/cas/v1/tickets";
+        final String username = "admin";
+        final String password = "maxkey";
+        final String service = "http://cas.demo.maxkey.top:8080/demo-cas/";
+        final String proxyValidate = "https://sso.maxkey.top/maxkey/authz/cas/p3/serviceValidate";
+ 
+        
+        ticketValidate(proxyValidate, getTicket(server, username, password, service), service);
+        
+    }
+ 
+    private static void warning(String msg) {
+        System.out.println(msg);
+    }
+ 
+    private static void info(String msg) {
+        System.out.println(msg);
+    }
+}
+