Jump to content

fesswood

Forum Members
  • Posts

    1
  • Joined

  • Last visited

Everything posted by fesswood

  1. Т.к. тема с примерами кода закрыта, отправлю сюда вариант на Kotlin + Ktor (gist): import kotlinx.serialization.Serializable import io.ktor.http.* import java.security.MessageDigest import java.util.* import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.features.* import io.ktor.client.features.cookies.* import io.ktor.client.features.json.* import io.ktor.client.features.json.serializer.* import io.ktor.client.features.logging.* import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import kotlinx.coroutines.runBlocking private const val LOGIN = "login" private const val PASSWORD = "password" data class KeeneticAuthHeaderValues( val map: Map<KeeneticAuthHeaderEnum, String> ) { val xndmChallenge: String by lazy { map.getValue(KeeneticAuthHeaderEnum.XNDMChallenge) } val xndmRealm: String by lazy { map.getValue(KeeneticAuthHeaderEnum.XNDMRealm) } } @Serializable data class UserCredentials(val login: String, val password: String) fun Headers.asMap(): EnumMap<KeeneticAuthHeaderEnum, String> = EnumMap( entries().asSequence() .filter { it -> it.key in KeeneticAuthHeaderEnum.values().map { it.title } } .associate { header -> KeeneticAuthHeaderEnum.from(header.key) to header.value.first() } ) // However, here we have to use a custom byte to hex converter to get the hashed value in hexadecimal private fun printHexBinary(hash: ByteArray): String { val hexString = StringBuilder(2 * hash.size) for (i in hash.indices) { val hex = Integer.toHexString(0xff and hash[i].toInt()) if (hex.length == 1) { hexString.append('0') } hexString.append(hex) } return hexString.toString() } fun String.encodeMd5(): String { return printHexBinary(MessageDigest.getInstance("MD5").digest(toByteArray())) } // see more https://www.baeldung.com/sha-256-hashing-java fun String.encodeSha256(): String { // Java provides inbuilt MessageDigest class for SHA-256 hashing return printHexBinary(MessageDigest.getInstance("SHA-256").digest(toByteArray())) } fun main() = runBlocking { // HttpClientEngineFactory using a Coroutine based I/O implementation val client = HttpClient(CIO) { install(JsonFeature) { serializer = KotlinxSerializer(kotlinx.serialization.json.Json { ignoreUnknownKeys = true prettyPrint = true isLenient = true }) } //log all requests install(Logging) { logger = Logger.DEFAULT level = LogLevel.ALL } install(HttpCookies) { // Will keep an in-memory map with all the cookies from previous requests. storage = AcceptAllCookiesStorage() } } // try with resource kotlin way client.use { // do auth authorized(client) { // here we have authorize val interfaceInfo: HttpResponse = client.get("http://192.168.1.1/rci/show/interface?name=ISP") } } } private suspend fun authorized(client: HttpClient, body: suspend () -> Unit) { val unauthorizedResponse = client.get<HttpResponse>("http://192.168.1.1/auth") { expectSuccess = false } if (unauthorizedResponse.status == HttpStatusCode.Unauthorized) { val tokenAndRealm = KeeneticAuthHeaderValues(unauthorizedResponse.headers.asMap()) val authPostResponse = authRequest(client, tokenAndRealm, LOGIN, PASSWORD) if (authPostResponse.status == HttpStatusCode.OK) { body() } } else if(unauthorizedResponse.status == HttpStatusCode.OK){ body() } } private suspend fun authRequest( client: HttpClient, tokenAndRealm: KeeneticAuthHeaderValues, ): HttpResponse { val authPostResponse = client.post<HttpResponse>("http://192.168.1.1/auth") { contentType(ContentType.Application.Json) expectSuccess = false val md5 = (LOGIN + ":" + tokenAndRealm.xndmRealm + ':' + PASSWORD).encodeMd5() body = UserCredentials( login = LOGIN, password = (tokenAndRealm.xndmChallenge + md5).encodeSha256() ) } return authPostResponse }
×
×
  • Create New...