union-ark-web 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROJECT_OVERVIEW.md +405 -0
- package/README.md +177 -0
- package/ark-control/pom.xml +142 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SecurityResult.java +14 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SymmetricalSecurityService.java +11 -0
- package/ark-control/src/local-mock/java/com/epcc/dubbo/result/Result.java +29 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptField.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldLong.java +17 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldWithTag.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/BaseDataErrorCode.java +26 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/CheckException.java +33 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/ErrorCode.java +9 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/redis/RedisCacheService.java +131 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/Constant.java +24 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/ResultUtil.java +9 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalMockSensitiveProxy.java +40 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalRedisCacheService.java +45 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveHostConfiguration.java +27 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveProxyConfiguration.java +16 -0
- package/ark-control/src/main/java/com/union/control/ArkControlApplication.java +17 -0
- package/ark-control/src/main/java/com/union/control/dubbo/ProviderAccessLogFilter.java +45 -0
- package/ark-control/src/main/java/com/union/control/mapper/AgentExecutionMapper.java +35 -0
- package/ark-control/src/main/java/com/union/control/mapper/ConversationMapper.java +44 -0
- package/ark-control/src/main/java/com/union/control/mapper/MemoryStoreMapper.java +41 -0
- package/ark-control/src/main/java/com/union/control/mapper/ScheduledTaskMapper.java +96 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveAddressBookDemo.java +31 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveDataDemoMapper.java +24 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AESInterceptor.java +265 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AddressBookHandler.java +105 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledExecutionToken.java +55 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledTaskScheduler.java +206 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentExecutionServiceImpl.java +212 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentProxyServiceImpl.java +143 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ConversationServiceImpl.java +245 -0
- package/ark-control/src/main/java/com/union/control/service/impl/MemoryStoreServiceImpl.java +252 -0
- package/ark-control/src/main/java/com/union/control/service/impl/RunningAnalysisMockServiceImpl.java +301 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ScheduledTaskServiceImpl.java +576 -0
- package/ark-control/src/main/java/com/union/control/service/impl/SensitiveDataDemoServiceImpl.java +144 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/RedisRevealTokenStore.java +90 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealProcessor.java +319 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealServiceImpl.java +72 -0
- package/ark-control/src/main/java/com/union/control/utils/AgentSupport.java +103 -0
- package/ark-control/src/main/java/com/union/control/utils/security/SymmetricalSecurityUtils.java +160 -0
- package/ark-control/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter +1 -0
- package/ark-control/src/main/resources/application.properties +4 -0
- package/ark-control/src/main/resources/application.yml +32 -0
- package/ark-control/src/main/resources/dubbo-provider.xml +20 -0
- package/ark-control/src/main/resources/mapper/AgentExecutionMapper.xml +75 -0
- package/ark-control/src/main/resources/mapper/ConversationMapper.xml +110 -0
- package/ark-control/src/main/resources/mapper/MemoryStoreMapper.xml +74 -0
- package/ark-control/src/main/resources/mapper/ScheduledTaskMapper.xml +286 -0
- package/ark-control/src/main/resources/mapper/SensitiveDataDemoMapper.xml +55 -0
- package/ark-control/src/main/resources/schema.sql +146 -0
- package/ark-control/src/test/java/com/union/control/AgentExecutionServiceTest.java +170 -0
- package/ark-control/src/test/java/com/union/control/ArkControlStructureContractTest.java +107 -0
- package/ark-control/src/test/java/com/union/control/ConversationServiceTest.java +89 -0
- package/ark-control/src/test/java/com/union/control/MemoryStoreServiceTest.java +26 -0
- package/ark-control/src/test/java/com/union/control/PydanticAiControlContractTest.java +52 -0
- package/ark-control/src/test/java/com/union/control/TestJson.java +45 -0
- package/ark-control/src/test/java/com/union/control/dubbo/ProviderAccessLogFilterTest.java +53 -0
- package/ark-control/src/test/java/com/union/control/local/sensitive/LocalSensitiveProxyConfigurationTest.java +23 -0
- package/ark-control/src/test/java/com/union/control/mapper/interceptor/AESInterceptorCompatibilityTest.java +505 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledExecutionTokenTest.java +27 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledTaskSchedulerTest.java +51 -0
- package/ark-control/src/test/java/com/union/control/service/AgentProxyServiceTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/ScheduledTaskServiceTest.java +483 -0
- package/ark-control/src/test/java/com/union/control/service/impl/SensitiveDataDemoServiceImplTest.java +104 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/RedisRevealTokenStoreTest.java +65 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealBoundaryTest.java +99 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorCodecTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/utils/security/SymmetricalSecurityUtilsCompatibilityTest.java +87 -0
- package/ark-control-facade/pom.xml +16 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentExecutionService.java +8 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentProxyService.java +7 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentResponse.java +22 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ConversationService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/MemoryStoreService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/RunningAnalysisMockService.java +10 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ScheduledTaskService.java +40 -0
- package/ark-control-facade/src/main/java/com/union/control/service/SensitiveDataDemoService.java +13 -0
- package/ark-control-facade/src/main/java/com/union/control/service/sensitive/SensitiveRevealService.java +18 -0
- package/ark-web/README.md +80 -0
- package/ark-web/pom.xml +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/ArkAuthServiceMock.java +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/LocalKaptchaConfiguration.java +26 -0
- package/ark-web/src/main/java/com/epcc/arkweb/Application.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/InterceptorConfig.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/Realm.java +64 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/ShiroConfig.java +129 -0
- package/ark-web/src/main/java/com/epcc/arkweb/filter/LoginFormFilter.java +43 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthContextHolder.java +39 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthenticatedRequest.java +91 -0
- package/ark-web/src/main/java/com/epcc/arkweb/model/ShiroUser.java +21 -0
- package/ark-web/src/main/java/com/epcc/arkweb/utils/ResultMsg.java +19 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskCommandVO.java +30 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskQueryVO.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/CommonController.java +25 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptor.java +229 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentController.java +165 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentPermission.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/LlmController.java +209 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/ScheduledTaskController.java +160 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveCaptchaService.java +146 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealController.java +163 -0
- package/ark-web/src/main/resources/application.properties +1 -0
- package/ark-web/src/main/resources/application.yml +23 -0
- package/ark-web/src/main/resources/dubbo-consumer.xml +19 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/CasShiroConfig.java +229 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/InterceptorConfig.java +35 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/ShiroConfig.java +161 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ArkWebStructureContractTest.java +290 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ShiroTestSupport.java +32 -0
- package/ark-web/src/test/java/com/epcc/arkweb/config/LocalShiroIntegrationTest.java +121 -0
- package/ark-web/src/test/java/com/epcc/arkweb/helper/AuthenticatedRequestTest.java +131 -0
- package/ark-web/src/test/java/com/epcc/arkweb/local/LocalArkAuthServiceMockTest.java +17 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptorTest.java +134 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentControllerAuthorizationTest.java +97 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/LlmControllerTest.java +113 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealControllerTest.java +273 -0
- package/package.json +18 -0
- package/pom.xml +16 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
import java.util.Map;
|
|
5
|
+
|
|
6
|
+
public interface ScheduledTaskService {
|
|
7
|
+
Map<String, Object> create(String input);
|
|
8
|
+
Map<String, Object> update(String input);
|
|
9
|
+
Map<String, Object> list(String input);
|
|
10
|
+
Map<String, Object> detail(String input);
|
|
11
|
+
Map<String, Object> runs(String input);
|
|
12
|
+
Map<String, Object> runDetail(String input);
|
|
13
|
+
Map<String, Object> unread(String input);
|
|
14
|
+
Map<String, Object> start(String input);
|
|
15
|
+
Map<String, Object> pause(String input);
|
|
16
|
+
Map<String, Object> discard(String input);
|
|
17
|
+
Map<String, Object> open(String input);
|
|
18
|
+
Long claimDueRun();
|
|
19
|
+
List<Long> pendingRunIds(int limit);
|
|
20
|
+
boolean beginRun(long runId, String tokenHash, String expiresAt);
|
|
21
|
+
void completeFromProxy(long runId, Map<String, Object> result);
|
|
22
|
+
void failRun(long runId, String errorCode, String errorMessage);
|
|
23
|
+
int failStaleRuns(int maxRunSeconds);
|
|
24
|
+
/** Resolves an active run from the raw one-time token; the provider hashes it internally. */
|
|
25
|
+
Map<String, Object> resolveScheduledToken(String rawToken);
|
|
26
|
+
|
|
27
|
+
class NotFoundException extends RuntimeException {
|
|
28
|
+
private static final long serialVersionUID = 1L;
|
|
29
|
+
public NotFoundException() {}
|
|
30
|
+
public NotFoundException(String message) { super(message); }
|
|
31
|
+
}
|
|
32
|
+
class ConflictException extends RuntimeException {
|
|
33
|
+
private static final long serialVersionUID = 1L;
|
|
34
|
+
public ConflictException() {}
|
|
35
|
+
public ConflictException(String message) { super(message); }
|
|
36
|
+
}
|
|
37
|
+
class DataCorruptionException extends RuntimeException {
|
|
38
|
+
private static final long serialVersionUID = 1L;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/ark-control-facade/src/main/java/com/union/control/service/SensitiveDataDemoService.java
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
import java.util.Map;
|
|
5
|
+
|
|
6
|
+
public interface SensitiveDataDemoService {
|
|
7
|
+
int insert(String input);
|
|
8
|
+
Map<String, Object> save(String input);
|
|
9
|
+
Map<String, Object> saveAddressBook(String input);
|
|
10
|
+
List<Map<String, Object>> query(String input);
|
|
11
|
+
int insertAddressBook(String input);
|
|
12
|
+
List<Map<String, Object>> queryAddressBook(String input);
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package com.union.control.service.sensitive;
|
|
2
|
+
|
|
3
|
+
public interface SensitiveRevealService {
|
|
4
|
+
String reveal(String input);
|
|
5
|
+
|
|
6
|
+
class InvalidTokenException extends RuntimeException {
|
|
7
|
+
private static final long serialVersionUID = 1L;
|
|
8
|
+
}
|
|
9
|
+
class ExpiredTokenException extends RuntimeException {
|
|
10
|
+
private static final long serialVersionUID = 1L;
|
|
11
|
+
}
|
|
12
|
+
class RevealDecryptionException extends RuntimeException {
|
|
13
|
+
private static final long serialVersionUID = 1L;
|
|
14
|
+
}
|
|
15
|
+
class StoreUnavailableException extends RuntimeException {
|
|
16
|
+
private static final long serialVersionUID = 1L;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# ark-web
|
|
2
|
+
|
|
3
|
+
This is the browser-facing module merged into the existing production Web
|
|
4
|
+
application. It owns the new HTTP controllers and final SSE response while
|
|
5
|
+
reusing the production Shiro Realm and Filter implementations.
|
|
6
|
+
Its standalone startup uses the production class and bean names
|
|
7
|
+
`ShiroConfig`, `Realm`, `LoginFormFilter`, and `InterceptorConfig`, and follows
|
|
8
|
+
the same Shiro Filter -> Realm -> Subject -> permission path. Production uses
|
|
9
|
+
the host application's existing implementations.
|
|
10
|
+
Business and persistence services are consumed from
|
|
11
|
+
`ark-control` through `ark-control-facade` Dubbo references.
|
|
12
|
+
|
|
13
|
+
The production Web application remains Shiro authenticated. Task persistence,
|
|
14
|
+
due-run claiming, execution tokens, workers and model calls stay in the control
|
|
15
|
+
provider. There is no Web-only scheduled facade or local scheduled-service
|
|
16
|
+
adapter:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
ark-web/src/main/java/com/epcc/arkweb/
|
|
20
|
+
vo/llm/ScheduledTaskCommandVO.java
|
|
21
|
+
vo/llm/ScheduledTaskQueryVO.java
|
|
22
|
+
web/llm/ScheduledTaskController.java
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`ScheduledTaskController` uses
|
|
26
|
+
`com.union.control.service.ScheduledTaskService` from the shared facade. Its
|
|
27
|
+
implementation is published by `ark-control`.
|
|
28
|
+
|
|
29
|
+
`AgentController` keeps the production CAS path for interactive py calls. Its
|
|
30
|
+
scheduled authorization endpoint validates a Control-issued token and performs
|
|
31
|
+
the real-time role-resource check. Agent tools use a non-Shiro
|
|
32
|
+
`@AgentPermission` guard and a Control-backed trusted context; only the
|
|
33
|
+
`X-Agent-Trusted-Context` value returned by that endpoint is accepted for tool
|
|
34
|
+
calls. No scheduled Realm or synthetic Subject is created.
|
|
35
|
+
The controller lives under `/agent/**`; it must not use production's anonymous
|
|
36
|
+
`/api/**` namespace. Both production filter-chain maps place `/agent/** -> anon`
|
|
37
|
+
before `/** -> authc`, delegating this exact namespace to the fail-closed Agent
|
|
38
|
+
guard. No scheduled Shiro Filter or Realm is introduced.
|
|
39
|
+
|
|
40
|
+
The copy-ready production files live under `src/production-overlay/java` and
|
|
41
|
+
are not part of the standalone module's compilation source set. The two Shiro
|
|
42
|
+
files differ from production only by the `/agent/**` whitelist line; the
|
|
43
|
+
`InterceptorConfig` copy registers the Agent guard first and excludes
|
|
44
|
+
`/agent/**` from the production browser-only interceptors. During production
|
|
45
|
+
merge, copy these over the three matching files rather than adding parallel
|
|
46
|
+
configuration classes.
|
|
47
|
+
|
|
48
|
+
For local authentication testing, activate `local-auth-mock`. It establishes a
|
|
49
|
+
normal Shiro Subject automatically, so no login page or manual cookie is needed.
|
|
50
|
+
Scheduled headers skip auto-login and continue through the non-Shiro Agent
|
|
51
|
+
guard. The only local replacement is the external `arkAuthService` bean at
|
|
52
|
+
`src/local-mock/java/com/epcc/arkweb/mock/ArkAuthServiceMock.java`; configure it
|
|
53
|
+
with `LOCAL_USER_ID`, `LOCAL_PASSWORD`, `LOCAL_ORG_CODE`, and
|
|
54
|
+
`LOCAL_AUTHORIZED_ROLE_ID`.
|
|
55
|
+
|
|
56
|
+
`ShiroUser`, `AuthContextHolder` and `ResultMsg` remain Web-owned types and do
|
|
57
|
+
not cross the Dubbo boundary.
|
|
58
|
+
|
|
59
|
+
The controller deliberately:
|
|
60
|
+
|
|
61
|
+
- follows the existing `web/llm`, `vo` and `service` package layout;
|
|
62
|
+
- exposes both `/llm/**` and `/union-op/llm/**` like the current production
|
|
63
|
+
`LLMController`;
|
|
64
|
+
- uses the existing `/assistantManager/page` Shiro permission;
|
|
65
|
+
- gets `loginName`, `orgCode`, and the selected `roleId` only from the
|
|
66
|
+
production Shiro identity exposed by `AuthContextHolder`;
|
|
67
|
+
- browser-facing methods never accept user identity, permissions or an
|
|
68
|
+
execution token from the browser. The internal scheduled authorization method
|
|
69
|
+
accepts only the Control-issued token from py-app.
|
|
70
|
+
|
|
71
|
+
Before enabling scheduling, verify the production `arkAuthService` bean is
|
|
72
|
+
available and fails closed when its backing service cannot be reached. The local
|
|
73
|
+
build has no proprietary auth-facade dependency, so the Agent-only guard invokes the unchanged production
|
|
74
|
+
`queryResource(roleId, userName, traceNo)` contract reflectively.
|
|
75
|
+
|
|
76
|
+
`LlmController#chatMessage` posts directly to py-app and writes and flushes each
|
|
77
|
+
upstream chunk to `HttpServletResponse`. The streaming path does not use Dubbo.
|
|
78
|
+
|
|
79
|
+
Production HTTP and Dubbo filters must not log Agent cookies, request payloads,
|
|
80
|
+
responses, or SSE chunks.
|
package/ark-web/pom.xml
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
5
|
+
<modelVersion>4.0.0</modelVersion>
|
|
6
|
+
<parent>
|
|
7
|
+
<groupId>org.springframework.boot</groupId>
|
|
8
|
+
<artifactId>spring-boot-starter-parent</artifactId>
|
|
9
|
+
<version>1.5.22.RELEASE</version>
|
|
10
|
+
<relativePath/>
|
|
11
|
+
</parent>
|
|
12
|
+
<groupId>com.nucc.channel.ark</groupId>
|
|
13
|
+
<artifactId>ark-web</artifactId>
|
|
14
|
+
<version>1.1-local</version>
|
|
15
|
+
<packaging>jar</packaging>
|
|
16
|
+
|
|
17
|
+
<properties>
|
|
18
|
+
<java.version>1.8</java.version>
|
|
19
|
+
<shiro.version>1.12.0</shiro.version>
|
|
20
|
+
</properties>
|
|
21
|
+
|
|
22
|
+
<dependencies>
|
|
23
|
+
<dependency>
|
|
24
|
+
<groupId>com.union</groupId>
|
|
25
|
+
<artifactId>ark-control-facade</artifactId>
|
|
26
|
+
<version>1.0.0</version>
|
|
27
|
+
</dependency>
|
|
28
|
+
<dependency>
|
|
29
|
+
<groupId>com.alibaba</groupId>
|
|
30
|
+
<artifactId>dubbo</artifactId>
|
|
31
|
+
<version>2.6.9</version>
|
|
32
|
+
<exclusions>
|
|
33
|
+
<exclusion><groupId>org.jboss.netty</groupId><artifactId>netty</artifactId></exclusion>
|
|
34
|
+
<exclusion><groupId>org.springframework</groupId><artifactId>spring</artifactId></exclusion>
|
|
35
|
+
<exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion>
|
|
36
|
+
</exclusions>
|
|
37
|
+
</dependency>
|
|
38
|
+
<dependency>
|
|
39
|
+
<groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.25.Final</version>
|
|
40
|
+
</dependency>
|
|
41
|
+
<dependency>
|
|
42
|
+
<groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.12.0</version>
|
|
43
|
+
</dependency>
|
|
44
|
+
<dependency>
|
|
45
|
+
<groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.13</version>
|
|
46
|
+
<exclusions>
|
|
47
|
+
<exclusion><groupId>io.netty</groupId><artifactId>netty</artifactId></exclusion>
|
|
48
|
+
<exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion>
|
|
49
|
+
<exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion>
|
|
50
|
+
</exclusions>
|
|
51
|
+
</dependency>
|
|
52
|
+
<dependency>
|
|
53
|
+
<groupId>org.springframework.boot</groupId>
|
|
54
|
+
<artifactId>spring-boot-starter-web</artifactId>
|
|
55
|
+
</dependency>
|
|
56
|
+
<dependency>
|
|
57
|
+
<groupId>org.apache.shiro</groupId>
|
|
58
|
+
<artifactId>shiro-spring</artifactId>
|
|
59
|
+
<version>${shiro.version}</version>
|
|
60
|
+
</dependency>
|
|
61
|
+
<dependency>
|
|
62
|
+
<groupId>org.apache.commons</groupId>
|
|
63
|
+
<artifactId>commons-lang3</artifactId>
|
|
64
|
+
<version>3.3</version>
|
|
65
|
+
</dependency>
|
|
66
|
+
<!-- Already supplied by the production Web parent. -->
|
|
67
|
+
<dependency>
|
|
68
|
+
<groupId>com.github.penggle</groupId>
|
|
69
|
+
<artifactId>kaptcha</artifactId>
|
|
70
|
+
<version>2.3.2</version>
|
|
71
|
+
</dependency>
|
|
72
|
+
<dependency>
|
|
73
|
+
<groupId>org.springframework.boot</groupId>
|
|
74
|
+
<artifactId>spring-boot-starter-test</artifactId>
|
|
75
|
+
<scope>test</scope>
|
|
76
|
+
</dependency>
|
|
77
|
+
</dependencies>
|
|
78
|
+
|
|
79
|
+
<build>
|
|
80
|
+
<plugins>
|
|
81
|
+
<plugin>
|
|
82
|
+
<groupId>org.codehaus.mojo</groupId>
|
|
83
|
+
<artifactId>build-helper-maven-plugin</artifactId>
|
|
84
|
+
<version>3.2.0</version>
|
|
85
|
+
<executions>
|
|
86
|
+
<execution>
|
|
87
|
+
<id>add-local-mock-source</id>
|
|
88
|
+
<phase>generate-sources</phase>
|
|
89
|
+
<goals><goal>add-source</goal></goals>
|
|
90
|
+
<configuration>
|
|
91
|
+
<sources><source>src/local-mock/java</source></sources>
|
|
92
|
+
</configuration>
|
|
93
|
+
</execution>
|
|
94
|
+
</executions>
|
|
95
|
+
</plugin>
|
|
96
|
+
<plugin>
|
|
97
|
+
<groupId>org.springframework.boot</groupId>
|
|
98
|
+
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
99
|
+
<configuration>
|
|
100
|
+
<mainClass>com.epcc.arkweb.Application</mainClass>
|
|
101
|
+
</configuration>
|
|
102
|
+
</plugin>
|
|
103
|
+
</plugins>
|
|
104
|
+
</build>
|
|
105
|
+
</project>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
package com.epcc.arkweb.mock;
|
|
2
|
+
|
|
3
|
+
import com.epcc.arkweb.model.ShiroUser;
|
|
4
|
+
import org.apache.shiro.SecurityUtils;
|
|
5
|
+
import org.apache.shiro.authc.UsernamePasswordToken;
|
|
6
|
+
import org.apache.shiro.web.servlet.AdviceFilter;
|
|
7
|
+
import org.springframework.beans.factory.annotation.Value;
|
|
8
|
+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
9
|
+
import org.springframework.context.annotation.Bean;
|
|
10
|
+
import org.springframework.context.annotation.Profile;
|
|
11
|
+
import org.springframework.stereotype.Component;
|
|
12
|
+
|
|
13
|
+
import java.util.Arrays;
|
|
14
|
+
import java.util.Collections;
|
|
15
|
+
import java.util.LinkedHashSet;
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.Set;
|
|
18
|
+
import javax.servlet.ServletRequest;
|
|
19
|
+
import javax.servlet.ServletResponse;
|
|
20
|
+
import javax.servlet.http.HttpServletRequest;
|
|
21
|
+
|
|
22
|
+
/** Local replacement for the external arkAuthService bean. */
|
|
23
|
+
@Component("arkAuthService")
|
|
24
|
+
@Profile("local-auth-mock")
|
|
25
|
+
public final class ArkAuthServiceMock {
|
|
26
|
+
private final String userId;
|
|
27
|
+
private final String password;
|
|
28
|
+
private final String orgCode;
|
|
29
|
+
private final String authorizedRoleId;
|
|
30
|
+
|
|
31
|
+
public ArkAuthServiceMock(
|
|
32
|
+
@Value("${agent.local-user-id:user-1}") String userId,
|
|
33
|
+
@Value("${agent.local-password:local-only}") String password,
|
|
34
|
+
@Value("${agent.local-org-code:104100000004}") String orgCode,
|
|
35
|
+
@Value("${agent.local-authorized-role-id:role-1}") String authorizedRoleId) {
|
|
36
|
+
this.userId = userId;
|
|
37
|
+
this.password = password;
|
|
38
|
+
this.orgCode = orgCode;
|
|
39
|
+
this.authorizedRoleId = authorizedRoleId;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public ShiroUser authenticate(String userName, char[] suppliedPassword) {
|
|
43
|
+
if (!userId.equals(userName)
|
|
44
|
+
|| !Arrays.equals(password.toCharArray(), suppliedPassword)) return null;
|
|
45
|
+
ShiroUser user = new ShiroUser();
|
|
46
|
+
user.setLoginName(userId);
|
|
47
|
+
user.setOrgCode(orgCode);
|
|
48
|
+
user.setRoleId(authorizedRoleId);
|
|
49
|
+
return user;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public Set<String> queryPermissions(String roleId, String userName) {
|
|
53
|
+
if (!authorizedRoleId.equals(roleId) || !userId.equals(userName))
|
|
54
|
+
return Collections.emptySet();
|
|
55
|
+
return Collections.unmodifiableSet(new LinkedHashSet<>(
|
|
56
|
+
Collections.singletonList("/assistantManager/page")));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Local requests get a normal Shiro Subject without a login page. */
|
|
60
|
+
@Bean("localAuthFilter")
|
|
61
|
+
public AdviceFilter localAuthFilter() {
|
|
62
|
+
return new AdviceFilter() {
|
|
63
|
+
@Override
|
|
64
|
+
protected boolean preHandle(ServletRequest request, ServletResponse response) {
|
|
65
|
+
HttpServletRequest http = (HttpServletRequest) request;
|
|
66
|
+
String authorization = http.getHeader("Authorization");
|
|
67
|
+
if ((authorization != null && authorization.startsWith("Scheduled "))
|
|
68
|
+
|| http.getHeader("X-Agent-Trusted-Context") != null)
|
|
69
|
+
return true;
|
|
70
|
+
if (!SecurityUtils.getSubject().isAuthenticated())
|
|
71
|
+
SecurityUtils.getSubject().login(
|
|
72
|
+
new UsernamePasswordToken(userId, password));
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The filter belongs only to Shiro's chain, not the servlet container's global chain. */
|
|
79
|
+
@Bean
|
|
80
|
+
public FilterRegistrationBean localAuthFilterRegistration(AdviceFilter localAuthFilter) {
|
|
81
|
+
FilterRegistrationBean registration = new FilterRegistrationBean(localAuthFilter);
|
|
82
|
+
registration.setEnabled(false);
|
|
83
|
+
return registration;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public Result queryResource(String roleId, String userName, String traceNo) {
|
|
87
|
+
List<Resource> resources = authorizedRoleId.equals(roleId) && userId.equals(userName)
|
|
88
|
+
? Collections.singletonList(new Resource("/assistantManager/page"))
|
|
89
|
+
: Collections.<Resource>emptyList();
|
|
90
|
+
return new Result(resources);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public static final class Result {
|
|
94
|
+
private final List<Resource> result;
|
|
95
|
+
Result(List<Resource> result) { this.result = result; }
|
|
96
|
+
public boolean isSuccess() { return true; }
|
|
97
|
+
public List<Resource> getResult() { return result; }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public static final class Resource {
|
|
101
|
+
private final String resourceUrl;
|
|
102
|
+
Resource(String resourceUrl) { this.resourceUrl = resourceUrl; }
|
|
103
|
+
public String getResourceUrl() { return resourceUrl; }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package com.epcc.arkweb.mock;
|
|
2
|
+
|
|
3
|
+
import com.google.code.kaptcha.Producer;
|
|
4
|
+
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
|
5
|
+
import com.google.code.kaptcha.util.Config;
|
|
6
|
+
import org.springframework.context.annotation.Bean;
|
|
7
|
+
import org.springframework.context.annotation.Configuration;
|
|
8
|
+
|
|
9
|
+
import java.util.Properties;
|
|
10
|
+
|
|
11
|
+
/** Local wiring only. Production supplies its existing KaptchaConfig / Producer bean. */
|
|
12
|
+
@Configuration
|
|
13
|
+
public class LocalKaptchaConfiguration {
|
|
14
|
+
@Bean
|
|
15
|
+
public Producer captchaProducer() {
|
|
16
|
+
Properties properties = new Properties();
|
|
17
|
+
properties.setProperty("kaptcha.image.width", "110");
|
|
18
|
+
properties.setProperty("kaptcha.image.height", "40");
|
|
19
|
+
properties.setProperty("kaptcha.textproducer.char.length", "4");
|
|
20
|
+
properties.setProperty("kaptcha.textproducer.font.size", "30");
|
|
21
|
+
properties.setProperty("kaptcha.textproducer.font.names", "SansSerif");
|
|
22
|
+
DefaultKaptcha producer = new DefaultKaptcha();
|
|
23
|
+
producer.setConfig(new Config(properties));
|
|
24
|
+
return producer;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.epcc.arkweb;
|
|
2
|
+
|
|
3
|
+
import org.springframework.boot.SpringApplication;
|
|
4
|
+
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
5
|
+
import org.springframework.context.annotation.ImportResource;
|
|
6
|
+
|
|
7
|
+
@SpringBootApplication
|
|
8
|
+
@ImportResource("classpath:dubbo-consumer.xml")
|
|
9
|
+
public class Application {
|
|
10
|
+
public static void main(String[] args) {
|
|
11
|
+
SpringApplication.run(Application.class, args);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package com.epcc.arkweb.config;
|
|
2
|
+
|
|
3
|
+
import com.epcc.arkweb.web.llm.AgentAuthorizationInterceptor;
|
|
4
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
5
|
+
import org.springframework.context.annotation.Configuration;
|
|
6
|
+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
|
7
|
+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
|
8
|
+
|
|
9
|
+
/** Uses the production configuration entry point for the Agent-only guard. */
|
|
10
|
+
@Configuration
|
|
11
|
+
public class InterceptorConfig extends WebMvcConfigurerAdapter {
|
|
12
|
+
@Autowired
|
|
13
|
+
private AgentAuthorizationInterceptor agentAuthorizationInterceptor;
|
|
14
|
+
|
|
15
|
+
@Override
|
|
16
|
+
public void addInterceptors(InterceptorRegistry registry) {
|
|
17
|
+
registry.addInterceptor(agentAuthorizationInterceptor)
|
|
18
|
+
.addPathPatterns("/agent/**");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
package com.epcc.arkweb.config;
|
|
2
|
+
|
|
3
|
+
import com.epcc.arkweb.model.ShiroUser;
|
|
4
|
+
import org.apache.shiro.SecurityUtils;
|
|
5
|
+
import org.apache.shiro.authc.AuthenticationException;
|
|
6
|
+
import org.apache.shiro.authc.AuthenticationInfo;
|
|
7
|
+
import org.apache.shiro.authc.AuthenticationToken;
|
|
8
|
+
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
|
9
|
+
import org.apache.shiro.authc.UsernamePasswordToken;
|
|
10
|
+
import org.apache.shiro.authz.AuthorizationInfo;
|
|
11
|
+
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
|
12
|
+
import org.apache.shiro.realm.AuthorizingRealm;
|
|
13
|
+
import org.apache.shiro.subject.PrincipalCollection;
|
|
14
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
15
|
+
import org.springframework.beans.factory.annotation.Qualifier;
|
|
16
|
+
|
|
17
|
+
import java.lang.reflect.InvocationTargetException;
|
|
18
|
+
import java.lang.reflect.Method;
|
|
19
|
+
import java.util.Set;
|
|
20
|
+
|
|
21
|
+
/** Local build of the production-named Realm; only its auth-service call is mocked. */
|
|
22
|
+
public class Realm extends AuthorizingRealm {
|
|
23
|
+
private Object arkAuthService;
|
|
24
|
+
|
|
25
|
+
@Autowired
|
|
26
|
+
public void setArkAuthService(@Qualifier("arkAuthService") Object arkAuthService) {
|
|
27
|
+
this.arkAuthService = arkAuthService;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Override
|
|
31
|
+
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
|
|
32
|
+
UsernamePasswordToken login = (UsernamePasswordToken) token;
|
|
33
|
+
ShiroUser user = invoke("authenticate",
|
|
34
|
+
new Class<?>[]{String.class, char[].class},
|
|
35
|
+
new Object[]{login.getUsername(), login.getPassword()}, ShiroUser.class);
|
|
36
|
+
if (user == null) throw new AuthenticationException("用户名或密码错误");
|
|
37
|
+
SecurityUtils.getSubject().getSession().setAttribute("wl_session_user_key", user);
|
|
38
|
+
return new SimpleAuthenticationInfo(user, login.getCredentials(), getName());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Override
|
|
42
|
+
@SuppressWarnings("unchecked")
|
|
43
|
+
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
|
44
|
+
ShiroUser user = principals.oneByType(ShiroUser.class);
|
|
45
|
+
if (user == null) return null;
|
|
46
|
+
Set<String> permissions = invoke("queryPermissions",
|
|
47
|
+
new Class<?>[]{String.class, String.class},
|
|
48
|
+
new Object[]{user.getRoleId(), user.getLoginName()}, Set.class);
|
|
49
|
+
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
|
50
|
+
info.setStringPermissions(permissions);
|
|
51
|
+
return info;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private <T> T invoke(String name, Class<?>[] types, Object[] args, Class<T> resultType) {
|
|
55
|
+
try {
|
|
56
|
+
Method method = arkAuthService.getClass().getMethod(name, types);
|
|
57
|
+
return resultType.cast(method.invoke(arkAuthService, args));
|
|
58
|
+
} catch (InvocationTargetException error) {
|
|
59
|
+
throw new AuthenticationException("鉴权服务调用失败", error.getCause());
|
|
60
|
+
} catch (Exception error) {
|
|
61
|
+
throw new AuthenticationException("鉴权服务调用失败", error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
package com.epcc.arkweb.config;
|
|
2
|
+
|
|
3
|
+
import com.epcc.arkweb.filter.LoginFormFilter;
|
|
4
|
+
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
|
|
5
|
+
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
|
|
6
|
+
import org.apache.shiro.mgt.SecurityManager;
|
|
7
|
+
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
|
8
|
+
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
|
9
|
+
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
|
10
|
+
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
|
11
|
+
import org.apache.shiro.web.servlet.SimpleCookie;
|
|
12
|
+
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
|
13
|
+
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
|
14
|
+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
15
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
16
|
+
import org.springframework.beans.factory.annotation.Qualifier;
|
|
17
|
+
import org.springframework.context.annotation.Bean;
|
|
18
|
+
import org.springframework.context.annotation.Configuration;
|
|
19
|
+
import org.springframework.context.annotation.DependsOn;
|
|
20
|
+
|
|
21
|
+
import javax.servlet.Filter;
|
|
22
|
+
import java.util.HashMap;
|
|
23
|
+
import java.util.LinkedHashMap;
|
|
24
|
+
import java.util.Map;
|
|
25
|
+
|
|
26
|
+
/** Standalone wiring with the same class, bean and filter names as production. */
|
|
27
|
+
@Configuration
|
|
28
|
+
@ConditionalOnProperty(prefix = "arkshiro", name = "sso", havingValue = "false")
|
|
29
|
+
public class ShiroConfig {
|
|
30
|
+
@Autowired(required = false)
|
|
31
|
+
@Qualifier("localAuthFilter")
|
|
32
|
+
private Filter localAuthFilter;
|
|
33
|
+
|
|
34
|
+
@Bean
|
|
35
|
+
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
|
|
36
|
+
ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean();
|
|
37
|
+
factory.setSecurityManager(securityManager);
|
|
38
|
+
factory.setLoginUrl("/login.html");
|
|
39
|
+
factory.setUnauthorizedUrl("/403.html");
|
|
40
|
+
factory.setSuccessUrl("/index.html");
|
|
41
|
+
|
|
42
|
+
Map<String, String> filterMap = new LinkedHashMap<>();
|
|
43
|
+
filterMap.put("/error", "anon");
|
|
44
|
+
filterMap.put("/css/**", "anon");
|
|
45
|
+
filterMap.put("/images/**", "anon");
|
|
46
|
+
filterMap.put("/script/**", "anon");
|
|
47
|
+
filterMap.put("/static/**", "anon");
|
|
48
|
+
filterMap.put("/plugins/**", "anon");
|
|
49
|
+
filterMap.put("/.ico", "anon");
|
|
50
|
+
filterMap.put("/healthcheck.html", "anon");
|
|
51
|
+
filterMap.put("/SSL/healthcheck.html", "anon");
|
|
52
|
+
filterMap.put("/agent/**", localAuthFilter == null ? "anon" : "localAuth,anon");
|
|
53
|
+
filterMap.put("/**", localAuthFilter == null ? "authc" : "localAuth,authc");
|
|
54
|
+
filterMap.put("/union-op/**", "authc");
|
|
55
|
+
factory.setFilterChainDefinitionMap(filterMap);
|
|
56
|
+
|
|
57
|
+
Map<String, Filter> filters = new HashMap<>();
|
|
58
|
+
filters.put("authc", new LoginFormFilter("LOCAL"));
|
|
59
|
+
if (localAuthFilter != null) filters.put("localAuth", localAuthFilter);
|
|
60
|
+
factory.setFilters(filters);
|
|
61
|
+
return factory;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Bean
|
|
65
|
+
public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
|
|
66
|
+
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
|
|
67
|
+
creator.setUsePrefix(true);
|
|
68
|
+
return creator;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Bean
|
|
72
|
+
public ModularRealmAuthenticator modularRealmAuthenticator() {
|
|
73
|
+
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
|
|
74
|
+
authenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
|
|
75
|
+
return authenticator;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@Bean
|
|
79
|
+
public DefaultWebSessionManager defaultWebSessionManager() {
|
|
80
|
+
DefaultWebSessionManager sessions = new DefaultWebSessionManager();
|
|
81
|
+
sessions.setGlobalSessionTimeout(1800000);
|
|
82
|
+
sessions.setDeleteInvalidSessions(true);
|
|
83
|
+
sessions.setSessionValidationSchedulerEnabled(true);
|
|
84
|
+
sessions.setSessionValidationInterval(900000);
|
|
85
|
+
SimpleCookie cookie = new SimpleCookie("SHRIOSESSIONID");
|
|
86
|
+
cookie.setHttpOnly(true);
|
|
87
|
+
sessions.setSessionIdCookie(new SimpleCookie(cookie));
|
|
88
|
+
sessions.setSessionIdUrlRewritingEnabled(false);
|
|
89
|
+
return sessions;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Bean
|
|
93
|
+
public DefaultWebSecurityManager defaultWebSecurityManager(
|
|
94
|
+
DefaultWebSessionManager sessions,
|
|
95
|
+
ModularRealmAuthenticator authenticator,
|
|
96
|
+
Realm realm) {
|
|
97
|
+
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
|
|
98
|
+
manager.setAuthenticator(authenticator);
|
|
99
|
+
manager.setRealm(realm);
|
|
100
|
+
manager.setSessionManager(sessions);
|
|
101
|
+
return manager;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Bean
|
|
105
|
+
public Realm arkRealm() {
|
|
106
|
+
return new Realm();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Bean
|
|
110
|
+
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
|
|
111
|
+
return new LifecycleBeanPostProcessor();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Bean
|
|
115
|
+
@DependsOn("lifecycleBeanPostProcessor")
|
|
116
|
+
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
|
|
117
|
+
DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
|
|
118
|
+
creator.setProxyTargetClass(true);
|
|
119
|
+
return creator;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Bean
|
|
123
|
+
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
|
|
124
|
+
SecurityManager securityManager) {
|
|
125
|
+
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
|
126
|
+
advisor.setSecurityManager(securityManager);
|
|
127
|
+
return advisor;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package com.epcc.arkweb.filter;
|
|
2
|
+
|
|
3
|
+
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
|
|
4
|
+
import org.apache.shiro.web.util.WebUtils;
|
|
5
|
+
|
|
6
|
+
import javax.servlet.ServletRequest;
|
|
7
|
+
import javax.servlet.ServletResponse;
|
|
8
|
+
import javax.servlet.http.HttpServletRequest;
|
|
9
|
+
import javax.servlet.http.HttpServletResponse;
|
|
10
|
+
import java.util.Map;
|
|
11
|
+
|
|
12
|
+
/** Production-named form filter; proprietary session telemetry is outside the local build. */
|
|
13
|
+
public class LoginFormFilter extends FormAuthenticationFilter {
|
|
14
|
+
private final String propFlag;
|
|
15
|
+
|
|
16
|
+
public LoginFormFilter(String propFlag) {
|
|
17
|
+
this.propFlag = propFlag;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@Override
|
|
21
|
+
protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
|
|
22
|
+
throws Exception {
|
|
23
|
+
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
24
|
+
if (isLoginRequest(request, response)) {
|
|
25
|
+
return !isLoginSubmission(request, response) || executeLogin(request, response);
|
|
26
|
+
}
|
|
27
|
+
httpResponse.setStatus(401);
|
|
28
|
+
if (!isAjax((HttpServletRequest) request))
|
|
29
|
+
WebUtils.issueRedirect(request, response,
|
|
30
|
+
wrapperUrl((HttpServletRequest) request), (Map) null, true, false);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private boolean isAjax(HttpServletRequest request) {
|
|
35
|
+
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private String wrapperUrl(HttpServletRequest request) {
|
|
39
|
+
if (propFlag.contains("DMZ")) return "/union-op/login.html";
|
|
40
|
+
return request.getServletPath().contains("/union-op")
|
|
41
|
+
? "/union-op/login.html" : "/login.html";
|
|
42
|
+
}
|
|
43
|
+
}
|